mirror of
https://github.com/geekammo/MicroView-Arduino-Library.git
synced 2026-02-20 03:21:30 +01:00
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
82d55a8201 | ||
|
|
d28428ce35 | ||
|
|
77faa7d583 | ||
|
|
eb9edb19d6 | ||
|
|
21fa22bec2 | ||
|
|
5afff4bff7 | ||
|
|
8d2802f6c1 | ||
|
|
c67593e321 | ||
|
|
f398624f85 | ||
|
|
9c5568418a | ||
|
|
a32fd2c499 | ||
|
|
499594d9de | ||
|
|
fa09bdd7aa | ||
|
|
b109908d28 | ||
|
|
b5462c5bcb | ||
|
|
7b66741f79 | ||
|
|
c1e8756c4e |
510
MicroView.cpp
510
MicroView.cpp
@@ -60,18 +60,18 @@ Page buffer is required because in SPI mode, the host cannot read the SSD1306's
|
||||
static uint8_t screenmemory [] = {
|
||||
// LCD Memory organised in 64 horizontal pixel and 6 rows of byte
|
||||
// B B .............B -----
|
||||
// y y .............y \
|
||||
// t t .............t \
|
||||
// e e .............e \
|
||||
// 0 1 .............63 \
|
||||
// \
|
||||
// D0 D0.............D0 \
|
||||
// D1 D1.............D1 / ROW 0
|
||||
// D2 D2.............D2 /
|
||||
// D3 D3.............D3 /
|
||||
// D4 D4.............D4 /
|
||||
// D5 D5.............D5 /
|
||||
// D6 D6.............D6 /
|
||||
// y y .............y |
|
||||
// t t .............t |
|
||||
// e e .............e |
|
||||
// 0 1 .............63 |
|
||||
// |
|
||||
// D0 D0.............D0 | ROW 0
|
||||
// D1 D1.............D1 |
|
||||
// D2 D2.............D2 |
|
||||
// D3 D3.............D3 |
|
||||
// D4 D4.............D4 |
|
||||
// D5 D5.............D5 |
|
||||
// D6 D6.............D6 |
|
||||
// D7 D7.............D7 ----
|
||||
|
||||
//SparkFun Electronics LOGO
|
||||
@@ -123,119 +123,116 @@ void MicroView::begin() {
|
||||
setColor(WHITE);
|
||||
setDrawMode(NORM);
|
||||
setCursor(0,0);
|
||||
|
||||
RESETLOW;
|
||||
|
||||
// Enable 3.3V power to the display
|
||||
pinMode(OLEDPWR, OUTPUT);
|
||||
digitalWrite(OLEDPWR,HIGH);
|
||||
// Setting up SPI pins
|
||||
pinMode(MOSI, OUTPUT);
|
||||
pinMode(SCK, OUTPUT);
|
||||
|
||||
//pinMode(DC, OUTPUT);
|
||||
pinMode(RESET, OUTPUT);
|
||||
pinMode(SS, INPUT);
|
||||
digitalWrite(SS, HIGH);
|
||||
|
||||
ssport = portOutputRegister(digitalPinToPort(SS));
|
||||
sspinmask = digitalPinToBitMask(SS);
|
||||
ssreg = portModeRegister(digitalPinToPort(SS));
|
||||
|
||||
dcport = portOutputRegister(digitalPinToPort(DC));
|
||||
dcpinmask = digitalPinToBitMask(DC);
|
||||
dcreg = portModeRegister(digitalPinToPort(DC));
|
||||
|
||||
digitalWrite(RESET, HIGH);
|
||||
// VDD (3.3V) goes high at start, lets just chill for 5 ms
|
||||
digitalWrite(OLEDPWR, HIGH);
|
||||
|
||||
// Give some time for power to stabilise
|
||||
delay(10);
|
||||
|
||||
RESETHIGH;
|
||||
delay(5);
|
||||
// bring reset low
|
||||
digitalWrite(RESET, LOW);
|
||||
|
||||
RESETLOW;
|
||||
|
||||
// Setup SPI frequency
|
||||
MVSPI.setClockDivider(SPI_CLOCK_DIV2);
|
||||
// Initialise SPI
|
||||
MVSPI.begin();
|
||||
|
||||
// wait 10ms
|
||||
delay(10);
|
||||
|
||||
delay(5);
|
||||
|
||||
// bring out of reset
|
||||
pinMode(RESET,INPUT_PULLUP);
|
||||
//digitalWrite(RESET, HIGH);
|
||||
RESETHIGH;
|
||||
|
||||
delay(10);
|
||||
|
||||
// Init sequence for 64x48 OLED module
|
||||
command(DISPLAYOFF); // 0xAE
|
||||
|
||||
command(SETDISPLAYCLOCKDIV); // 0xD5
|
||||
command(0x80); // the suggested ratio 0x80
|
||||
|
||||
command(SETMULTIPLEX); // 0xA8
|
||||
command(0x2F);
|
||||
|
||||
command(SETDISPLAYOFFSET); // 0xD3
|
||||
command(0x0); // no offset
|
||||
|
||||
command(SETSTARTLINE | 0x0); // line #0
|
||||
|
||||
command(CHARGEPUMP); // enable charge pump
|
||||
command(0x14);
|
||||
|
||||
command(NORMALDISPLAY); // 0xA6
|
||||
command(DISPLAYALLONRESUME); // 0xA4
|
||||
|
||||
// command(DISPLAYOFF); // 0xAE
|
||||
// command(SETDISPLAYCLOCKDIV, 0x80); // 0xD5 / the suggested ratio 0x80
|
||||
command(SETMULTIPLEX, 0x2F); // 0xA8
|
||||
// command(SETDISPLAYOFFSET, 0x0); // 0xD3 / no offset
|
||||
// command(SETSTARTLINE | 0x0); // 0x40 / line #0
|
||||
command(CHARGEPUMP, 0x14); // 0x8D / enable charge pump
|
||||
// command(NORMALDISPLAY); // 0xA6
|
||||
// command(DISPLAYALLONRESUME); // 0xA4
|
||||
command(SEGREMAP | 0x1);
|
||||
command(COMSCANDEC);
|
||||
// command(SETCOMPINS, 0x12); // 0xDA
|
||||
command(SETCONTRAST, 0x8F); // 0x81
|
||||
command(SETPRECHARGE, 0xF1); // 0xD9
|
||||
command(SETVCOMDESELECT, 0x40); // 0xDB
|
||||
command(DISPLAYON); //--turn on oled panel
|
||||
|
||||
command(SETCOMPINS); // 0xDA
|
||||
command(0x12);
|
||||
clear(ALL); // Erase hardware memory inside the OLED controller to avoid random data in memory.
|
||||
|
||||
command(SETCONTRAST); // 0x81
|
||||
command(0x8F);
|
||||
|
||||
command(SETPRECHARGE); // 0xd9
|
||||
command(0xF1);
|
||||
|
||||
command(SETVCOMDESELECT); // 0xDB
|
||||
command(0x40);
|
||||
|
||||
command(DISPLAYON); //--turn on oled panel
|
||||
clear(ALL); // Erase hardware memory inside the OLED controller to avoid random data in memory.
|
||||
Serial.begin(115200);
|
||||
}
|
||||
|
||||
/** \brief SPI command.
|
||||
|
||||
Setup DC and SS pins, then send command via SPI to SSD1306 controller.
|
||||
/** \brief Power off the OLED display.
|
||||
|
||||
Reset display control signals and
|
||||
prepare the SSD1306 controller for power off,
|
||||
then power off the 3.3V regulator.
|
||||
*/
|
||||
void MicroView::end() {
|
||||
DCLOW; // Just in case
|
||||
command(DISPLAYOFF);
|
||||
command(CHARGEPUMP, 0x10); // Disable the charge pump
|
||||
delay(150); // Wait for charge pump off
|
||||
RESETLOW;
|
||||
SSLOW;
|
||||
MVSPI.end(); // Disable SPI mode
|
||||
digitalWrite(OLEDPWR, LOW); // Power off the 3.3V regulator
|
||||
}
|
||||
|
||||
/** \brief Send 1 command byte.
|
||||
|
||||
Send 1 command byte via SPI to SSD1306 controller.
|
||||
*/
|
||||
void MicroView::command(uint8_t c) {
|
||||
// Hardware SPI
|
||||
*dcreg |= dcpinmask; // Set DC pin to OUTPUT
|
||||
*dcport &= ~dcpinmask; // DC pin LOW
|
||||
|
||||
*ssreg |= sspinmask; // Set SS pin to OUTPUT
|
||||
*ssport &= ~sspinmask; // SS LOW
|
||||
|
||||
MVSPI.packetBegin();
|
||||
MVSPI.transfer(c);
|
||||
MVSPI.packetEnd();
|
||||
}
|
||||
|
||||
*ssport |= sspinmask; // SS HIGH
|
||||
*ssreg &= ~sspinmask; // Set SS pin to INPUT
|
||||
|
||||
*dcreg &= ~dcpinmask; // Set DC to INPUT to avoid high voltage over driving the OLED logic
|
||||
/** \brief Send 2 command bytes.
|
||||
|
||||
Send 2 command bytes via SPI to SSD1306 controller.
|
||||
*/
|
||||
void MicroView::command(uint8_t c1, uint8_t c2) {
|
||||
MVSPI.packetBegin();
|
||||
MVSPI.transfer(c1);
|
||||
MVSPI.wait();
|
||||
MVSPI.transfer(c2);
|
||||
MVSPI.packetEnd();
|
||||
}
|
||||
|
||||
/** \brief Send 3 command bytes.
|
||||
|
||||
Send 3 command bytes via SPI to SSD1306 controller.
|
||||
*/
|
||||
void MicroView::command(uint8_t c1, uint8_t c2, uint8_t c3) {
|
||||
MVSPI.packetBegin();
|
||||
MVSPI.transfer(c1);
|
||||
MVSPI.wait();
|
||||
MVSPI.transfer(c2);
|
||||
MVSPI.wait();
|
||||
MVSPI.transfer(c3);
|
||||
MVSPI.packetEnd();
|
||||
}
|
||||
|
||||
/** \brief SPI data.
|
||||
|
||||
Setup DC and SS pins, then send data via SPI to SSD1306 controller.
|
||||
Send 1 data byte via SPI to SSD1306 controller.
|
||||
*/
|
||||
void MicroView::data(uint8_t c) {
|
||||
// Hardware SPI
|
||||
*dcport |= dcpinmask; // DC HIGH
|
||||
|
||||
*ssreg |= sspinmask; // Set SS pin to OUTPUT
|
||||
*ssport &= ~sspinmask; // SS LOW
|
||||
|
||||
MVSPI.packetBegin();
|
||||
DCHIGH;
|
||||
MVSPI.transfer(c);
|
||||
|
||||
*ssport |= sspinmask; // SS HIGH
|
||||
*ssreg &= ~sspinmask; // Set SS pin to INPUT
|
||||
|
||||
*dcreg &= ~dcpinmask; // Set DC to INPUT to avoid high voltage over driving the OLED logic
|
||||
MVSPI.packetEnd();
|
||||
}
|
||||
|
||||
/** \brief Set SSD1306 page address.
|
||||
@@ -243,8 +240,7 @@ void MicroView::data(uint8_t c) {
|
||||
Send page address command and address to the SSD1306 OLED controller.
|
||||
*/
|
||||
void MicroView::setPageAddress(uint8_t add) {
|
||||
add=0xb0|add;
|
||||
command(add);
|
||||
command(SETPAGE|add);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -253,8 +249,7 @@ void MicroView::setPageAddress(uint8_t add) {
|
||||
Send column address command and address to the SSD1306 OLED controller.
|
||||
*/
|
||||
void MicroView::setColumnAddress(uint8_t add) {
|
||||
command((0x10|(add>>4))+0x02);
|
||||
command((0x0f&add));
|
||||
command((SETHIGHCOLUMN|(add>>4))+0x02, SETLOWCOLUMN|(0x0f&add));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -263,19 +258,25 @@ void MicroView::setColumnAddress(uint8_t add) {
|
||||
To clear GDRAM inside the LCD controller, pass in the variable mode = ALL and to clear screen page buffer pass in the variable mode = PAGE.
|
||||
*/
|
||||
void MicroView::clear(uint8_t mode) {
|
||||
// uint8_t page=6, col=0x40;
|
||||
if (mode==ALL) {
|
||||
for (int i=0;i<8; i++) {
|
||||
setPageAddress(i);
|
||||
setColumnAddress(0);
|
||||
for (int j=0; j<0x80; j++) {
|
||||
data(0);
|
||||
}
|
||||
command(SETADDRESSMODE, 0); // Set horizontal addressing mode
|
||||
command(SETCOLUMNBOUNDS, 0, LCDTOTALWIDTH - 1); // Set width
|
||||
command(SETPAGEBOUNDS, 0, LCDTOTALPAGES - 1); // Set height
|
||||
|
||||
MVSPI.packetBegin();
|
||||
DCHIGH;
|
||||
MVSPI.transfer(0);
|
||||
for (int i = 1; i < LCDTOTALWIDTH * LCDTOTALPAGES; i++) {
|
||||
MVSPI.wait();
|
||||
MVSPI.transfer(0);
|
||||
}
|
||||
MVSPI.packetEnd();
|
||||
|
||||
command(SETADDRESSMODE, 2); // Return display to page addressing mode
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(screenmemory,0,384); // (64 x 48) / 8 = 384
|
||||
memset(screenmemory, 0, LCDWIDTH * LCDPAGES);
|
||||
//display();
|
||||
}
|
||||
}
|
||||
@@ -285,19 +286,25 @@ void MicroView::clear(uint8_t mode) {
|
||||
To clear GDRAM inside the LCD controller, pass in the variable mode = ALL with c character and to clear screen page buffer, pass in the variable mode = PAGE with c character.
|
||||
*/
|
||||
void MicroView::clear(uint8_t mode, uint8_t c) {
|
||||
//uint8_t page=6, col=0x40;
|
||||
if (mode==ALL) {
|
||||
for (int i=0;i<8; i++) {
|
||||
setPageAddress(i);
|
||||
setColumnAddress(0);
|
||||
for (int j=0; j<0x80; j++) {
|
||||
data(c);
|
||||
}
|
||||
command(SETADDRESSMODE, 0); // Set horizontal addressing mode
|
||||
command(SETCOLUMNBOUNDS, 0, LCDTOTALWIDTH - 1); // Set width
|
||||
command(SETPAGEBOUNDS, 0, LCDTOTALPAGES - 1); // Set height
|
||||
|
||||
MVSPI.packetBegin();
|
||||
DCHIGH;
|
||||
MVSPI.transfer(c);
|
||||
for (int i = 1; i < LCDTOTALWIDTH * LCDTOTALPAGES; i++) {
|
||||
MVSPI.wait();
|
||||
MVSPI.transfer(c);
|
||||
}
|
||||
MVSPI.packetEnd();
|
||||
|
||||
command(SETADDRESSMODE, 2); // Return display to page addressing mode
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(screenmemory,c,384); // (64 x 48) / 8 = 384
|
||||
memset(screenmemory, c, LCDWIDTH * LCDPAGES);
|
||||
display();
|
||||
}
|
||||
}
|
||||
@@ -315,11 +322,10 @@ void MicroView::invert(boolean inv) {
|
||||
|
||||
/** \brief Set contrast.
|
||||
|
||||
OLED contract value from 0 to 255. Note: Contrast level is not very obvious.
|
||||
OLED contrast value from 0 to 255. Note: Contrast level is not very obvious.
|
||||
*/
|
||||
void MicroView::contrast(uint8_t contrast) {
|
||||
command(SETCONTRAST); // 0x81
|
||||
command(contrast);
|
||||
command(SETCONTRAST, contrast); // 0x81
|
||||
}
|
||||
|
||||
/** \brief Transfer display memory.
|
||||
@@ -327,15 +333,22 @@ void MicroView::contrast(uint8_t contrast) {
|
||||
Bulk move the screen buffer to the SSD1306 controller's memory so that images/graphics drawn on the screen buffer will be displayed on the OLED.
|
||||
*/
|
||||
void MicroView::display(void) {
|
||||
uint8_t i, j;
|
||||
|
||||
for (i=0; i<6; i++) {
|
||||
setPageAddress(i);
|
||||
setColumnAddress(0);
|
||||
for (j=0;j<0x40;j++) {
|
||||
data(screenmemory[i*0x40+j]);
|
||||
}
|
||||
command(SETADDRESSMODE, 0); // Set horizontal addressing mode
|
||||
command(SETCOLUMNBOUNDS,
|
||||
LCDCOLUMNOFFSET,
|
||||
LCDCOLUMNOFFSET + LCDWIDTH - 1); // Set width
|
||||
command(SETPAGEBOUNDS, 0, LCDPAGES - 1); // Set height
|
||||
|
||||
MVSPI.packetBegin();
|
||||
DCHIGH;
|
||||
MVSPI.transfer(screenmemory[0]);
|
||||
for (int i = 1; i < LCDWIDTH * LCDPAGES; i++) {
|
||||
MVSPI.wait();
|
||||
MVSPI.transfer(screenmemory[i]);
|
||||
}
|
||||
MVSPI.packetEnd();
|
||||
|
||||
command(SETADDRESSMODE, 2); // Restore to page addressing mode
|
||||
}
|
||||
|
||||
//#if ARDUINO >= 100
|
||||
@@ -847,14 +860,9 @@ size_t MicroView::write(uint8_t c) {
|
||||
if (stop<start) // stop must be larger or equal to start
|
||||
return;
|
||||
scrollStop(); // need to disable scrolling before starting to avoid memory corrupt
|
||||
command(RIGHTHORIZONTALSCROLL);
|
||||
command(0x00);
|
||||
command(start);
|
||||
command(0x7); // scroll speed frames , TODO
|
||||
command(stop);
|
||||
command(0x00);
|
||||
command(0xFF);
|
||||
command(ACTIVATESCROLL);
|
||||
command(RIGHTHORIZONTALSCROLL, 0);
|
||||
command(start, 0x7, stop); // scroll speed frames , TODO
|
||||
command(0x00, 0xFF, ACTIVATESCROLL);
|
||||
}
|
||||
|
||||
/** \brief Vertical flip.
|
||||
@@ -955,7 +963,7 @@ size_t MicroView::write(uint8_t c) {
|
||||
Serial.println(serCmd[2]);
|
||||
pixel(serCmd[1],serCmd[2]);
|
||||
display();
|
||||
} else if (cmdCount=4) {
|
||||
} else if (cmdCount==4) {
|
||||
Serial.print("pixel ");
|
||||
Serial.print(serCmd[1]);
|
||||
Serial.print(" ");
|
||||
@@ -1269,7 +1277,7 @@ size_t MicroView::write(uint8_t c) {
|
||||
temp=atoi(result);
|
||||
serCmd[index]=(uint8_t)temp & 0xff; // we only need 8 bit number
|
||||
index++;
|
||||
for (uint8_t i;i<recvLEN;i++) {
|
||||
for (uint8_t i=0;i<recvLEN;i++) {
|
||||
result=strtok(NULL,",");
|
||||
if (result != NULL) {
|
||||
|
||||
@@ -1411,17 +1419,29 @@ size_t MicroView::write(uint8_t c) {
|
||||
|
||||
/** \brief MicroViewSlider class initialisation with style.
|
||||
|
||||
Initialise the MicroViewSlider widget with style WIDGETSTYLE0 or WIDGETSTYLE1.
|
||||
Initialise the MicroViewSlider widget with style WIDGETSTYLE0 or WIDGETSTYLE1 or WIDGETSTYLE2 (like 0, but vertical) or WIDGETSTYLE3 (like 1, but vertical). If this list gets any longer, it might be better as a switch/case statement.
|
||||
*/
|
||||
MicroViewSlider::MicroViewSlider(uint8_t newx, uint8_t newy, int16_t min, int16_t max, uint8_t sty):MicroViewWidget(newx, newy, min, max) {
|
||||
if (sty==WIDGETSTYLE0) {
|
||||
style=0;
|
||||
totalTicks=30;
|
||||
}
|
||||
else {
|
||||
else if (sty==WIDGETSTYLE1) {
|
||||
style=1;
|
||||
totalTicks=60;
|
||||
}
|
||||
else if (sty==WIDGETSTYLE2) {
|
||||
style=2;
|
||||
totalTicks=20;
|
||||
}
|
||||
else if (sty==WIDGETSTYLE3) {
|
||||
style=3;
|
||||
totalTicks=40;
|
||||
}
|
||||
else { //unrecognized style, so use default
|
||||
style=0;
|
||||
totalTicks=30;
|
||||
}
|
||||
|
||||
needFirstDraw=true;
|
||||
prevValue=getMinValue();
|
||||
@@ -1438,31 +1458,39 @@ size_t MicroView::write(uint8_t c) {
|
||||
offsetX=getX();
|
||||
offsetY=getY();
|
||||
|
||||
if(style>0)
|
||||
majorLine=7;
|
||||
else
|
||||
majorLine=4;
|
||||
|
||||
// Draw major tickers
|
||||
for (uint8_t i=0; i<majorLine;i++) {
|
||||
uView.lineV(offsetX+1+(i*10), offsetY+3, 5);
|
||||
}
|
||||
// Draw minor tickers
|
||||
for (uint8_t i=0; i<4;i++) {
|
||||
uView.lineV(offsetX+3+(i*2), offsetY+5, 3);
|
||||
}
|
||||
for (uint8_t i=0; i<4;i++) {
|
||||
uView.lineV(offsetX+13+(i*2), offsetY+5, 3);
|
||||
}
|
||||
for (uint8_t i=0; i<4;i++) {
|
||||
uView.lineV(offsetX+23+(i*2), offsetY+5, 3);
|
||||
}
|
||||
|
||||
if(style>0) {
|
||||
for (uint8_t i=0; i<4;i++) {
|
||||
uView.lineV(offsetX+33+(i*2), offsetY+5, 3);
|
||||
if(style==0)
|
||||
majorLine=4;
|
||||
else if (style==1)
|
||||
majorLine=7;
|
||||
else if (style==2)
|
||||
majorLine=3;
|
||||
else if (style==3)
|
||||
majorLine=5;
|
||||
|
||||
|
||||
|
||||
//Horizontal styles, style 0 or 1
|
||||
|
||||
if (style==0 || style==1) {
|
||||
// Draw major tickers
|
||||
for (uint8_t i=0; i<majorLine;i++) {
|
||||
uView.lineV(offsetX+1+(i*10), offsetY+3, 5);
|
||||
}
|
||||
if (style>0) {
|
||||
// Draw minor tickers
|
||||
for (uint8_t i=0; i<4;i++) {
|
||||
uView.lineV(offsetX+3+(i*2), offsetY+5, 3);
|
||||
}
|
||||
for (uint8_t i=0; i<4;i++) {
|
||||
uView.lineV(offsetX+13+(i*2), offsetY+5, 3);
|
||||
}
|
||||
for (uint8_t i=0; i<4;i++) {
|
||||
uView.lineV(offsetX+23+(i*2), offsetY+5, 3);
|
||||
}
|
||||
|
||||
if(style==1) { //Longer line, more minor ticks
|
||||
for (uint8_t i=0; i<4;i++) {
|
||||
uView.lineV(offsetX+33+(i*2), offsetY+5, 3);
|
||||
}
|
||||
for (uint8_t i=0; i<4;i++) {
|
||||
uView.lineV(offsetX+43+(i*2), offsetY+5, 3);
|
||||
}
|
||||
@@ -1471,6 +1499,31 @@ size_t MicroView::write(uint8_t c) {
|
||||
}
|
||||
}
|
||||
}
|
||||
//Vertical styles, style 2 or 3
|
||||
else {
|
||||
// Draw major tickers
|
||||
for (uint8_t i=0; i<majorLine;i++) {
|
||||
uView.lineH(offsetX, offsetY+1+(i*10), 5);
|
||||
}
|
||||
// Draw minor tickers
|
||||
for (uint8_t i=0; i<4;i++) {
|
||||
uView.lineH(offsetX, offsetY+3+(i*2), 3);
|
||||
}
|
||||
for (uint8_t i=0; i<4;i++) {
|
||||
uView.lineH(offsetX, offsetY+13+(i*2), 3);
|
||||
}
|
||||
|
||||
if(style==3) { //Explicit test for style
|
||||
for (uint8_t i=0; i<4;i++) {
|
||||
uView.lineH(offsetX, offsetY+23+(i*2), 3);
|
||||
}
|
||||
for (uint8_t i=0; i<4;i++) {
|
||||
uView.lineH(offsetX, offsetY+33+(i*2), 3);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1486,29 +1539,55 @@ size_t MicroView::write(uint8_t c) {
|
||||
offsetY=getY();
|
||||
|
||||
if (needFirstDraw) {
|
||||
uView.lineH(offsetX+tickPosition,offsetY, 3, WHITE, XOR);
|
||||
uView.pixel(offsetX+1+tickPosition,offsetY+1, WHITE, XOR);
|
||||
if (style==0 || style==1){ //Horizontal
|
||||
uView.lineH(offsetX+tickPosition, offsetY, 3, WHITE, XOR);
|
||||
uView.pixel(offsetX+1+tickPosition, offsetY+1, WHITE, XOR);
|
||||
}
|
||||
else { //Vertical
|
||||
uView.lineV(offsetX+7, offsetY+tickPosition, 3, WHITE, XOR);
|
||||
uView.pixel(offsetX+6, offsetY+1+tickPosition, WHITE, XOR);
|
||||
}
|
||||
|
||||
sprintf(strBuffer,"%4d", prevValue); // we need to force 4 digit so that blank space will cover larger value
|
||||
needFirstDraw=false;
|
||||
}
|
||||
else {
|
||||
// Draw previous pointer in XOR mode to erase it
|
||||
tickPosition= (((float)(prevValue-getMinValue())/(float)(getMaxValue()-getMinValue()))*totalTicks);
|
||||
uView.lineH(offsetX+tickPosition,offsetY, 3, WHITE, XOR);
|
||||
uView.pixel(offsetX+1+tickPosition,offsetY+1, WHITE, XOR);
|
||||
if (style==0 || style==1){ //Horizontal
|
||||
uView.lineH(offsetX+tickPosition,offsetY, 3, WHITE, XOR);
|
||||
uView.pixel(offsetX+1+tickPosition,offsetY+1, WHITE, XOR);
|
||||
}
|
||||
else { //Vertical
|
||||
uView.lineV(offsetX+7, offsetY+tickPosition, 3, WHITE, XOR);
|
||||
uView.pixel(offsetX+6, offsetY+1+tickPosition, WHITE, XOR);
|
||||
}
|
||||
|
||||
// Draw current pointer
|
||||
tickPosition= (((float)(getValue()-getMinValue())/(float)(getMaxValue()-getMinValue()))*totalTicks);
|
||||
uView.lineH(offsetX+tickPosition,offsetY, 3, WHITE, XOR);
|
||||
uView.pixel(offsetX+1+tickPosition,offsetY+1, WHITE, XOR);
|
||||
if (style==0 || style==1){ //Horizontal
|
||||
uView.lineH(offsetX+tickPosition,offsetY, 3, WHITE, XOR);
|
||||
uView.pixel(offsetX+1+tickPosition,offsetY+1, WHITE, XOR);
|
||||
}
|
||||
else { //Vertical
|
||||
uView.lineV(offsetX+7, offsetY+tickPosition, 3, WHITE, XOR);
|
||||
uView.pixel(offsetX+6, offsetY+1+tickPosition, WHITE, XOR);
|
||||
}
|
||||
|
||||
sprintf(strBuffer,"%4d", getValue()); // we need to force 4 digit so that blank space will cover larger value
|
||||
prevValue=getValue();
|
||||
}
|
||||
|
||||
// Draw value
|
||||
if(style>0)
|
||||
uView.setCursor(offsetX,offsetY+10);
|
||||
else
|
||||
uView.setCursor(offsetX+34,offsetY+1);
|
||||
if(style==0)
|
||||
uView.setCursor(offsetX+34,offsetY+1);
|
||||
else if (style==1)
|
||||
uView.setCursor(offsetX,offsetY+10);
|
||||
else if (style==2)
|
||||
uView.setCursor(offsetX+1,offsetY+24);
|
||||
else //style==3
|
||||
uView.setCursor(offsetX+9,offsetY);
|
||||
|
||||
uView.print(strBuffer);
|
||||
}
|
||||
|
||||
@@ -1554,10 +1633,10 @@ size_t MicroView::write(uint8_t c) {
|
||||
|
||||
/** \brief Draw widget face.
|
||||
|
||||
Draw image/diagram represengint the widget's face.
|
||||
Draw image/diagram representing the widget's face.
|
||||
*/
|
||||
void MicroViewGauge::drawFace() {
|
||||
uint8_t offsetX, offsetY, majorLine;
|
||||
uint8_t offsetX, offsetY;
|
||||
float degreeSec, fromSecX, fromSecY, toSecX, toSecY;
|
||||
offsetX=getX();
|
||||
offsetY=getY();
|
||||
@@ -1591,8 +1670,7 @@ size_t MicroView::write(uint8_t c) {
|
||||
*/
|
||||
void MicroViewGauge::draw() {
|
||||
uint8_t offsetX, offsetY;
|
||||
uint8_t tickPosition=0;
|
||||
float degreeSec, fromSecX, fromSecY, toSecX, toSecY;
|
||||
float degreeSec, toSecX, toSecY;
|
||||
|
||||
char strBuffer[5];
|
||||
offsetX=getX();
|
||||
@@ -1635,44 +1713,74 @@ size_t MicroView::write(uint8_t c) {
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
// Slider Widget - end
|
||||
// Gauge Widget - end
|
||||
// -------------------------------------------------------------------------------------
|
||||
|
||||
/** \brief SPI Initialisation.
|
||||
|
||||
Setup SCK, MOSI pins for SPI transmission.
|
||||
Setup SCK, MOSI, SS and DC pins for SPI transmission.
|
||||
*/
|
||||
void MVSPIClass::begin() {
|
||||
// Set SS to high so a connected chip will be "deselected" by default
|
||||
digitalWrite(SS, HIGH);
|
||||
|
||||
// When the SS pin is set as OUTPUT, it can be used as
|
||||
// a general purpose output port (it doesn't influence
|
||||
// SPI operations).
|
||||
pinMode(SS, OUTPUT);
|
||||
|
||||
// Set SS to high so the display will be "deselected" by default
|
||||
SSHIGH;
|
||||
// Warning: if the SS pin ever becomes a LOW INPUT then SPI
|
||||
// automatically switches to Slave, so the data direction of
|
||||
// the SS pin MUST be kept as OUTPUT.
|
||||
SPCR |= _BV(MSTR);
|
||||
SPCR |= _BV(SPE);
|
||||
// automatically switches to Slave.
|
||||
// This should not occur with the MicroView as nothing can drive the pin.
|
||||
|
||||
// Set direction register for SCK and MOSI pin.
|
||||
// MISO pin automatically overrides to INPUT.
|
||||
// By doing this AFTER enabling SPI, we avoid accidentally
|
||||
// clocking in a single bit since the lines go directly
|
||||
// from "input" to SPI control.
|
||||
// http://code.google.com/p/arduino/issues/detail?id=888
|
||||
// Set DC low for command mode, where it should always default to unless
|
||||
// data is being transmitted.
|
||||
DCLOW;
|
||||
|
||||
// Set SCK and MOSI to be outputs and low when SPI is disabled.
|
||||
digitalWrite(SCK, LOW);
|
||||
digitalWrite(MOSI, LOW);
|
||||
pinMode(SCK, OUTPUT);
|
||||
pinMode(MOSI, OUTPUT);
|
||||
|
||||
// Set SPI master mode. Don't enable SPI at this time.
|
||||
SPCR |= _BV(MSTR);
|
||||
}
|
||||
|
||||
/** \brief End SPI. */
|
||||
void MVSPIClass::end() {
|
||||
SPCR &= ~_BV(SPE);
|
||||
// SCK and MOSI should already be low but set them again, to be sure.
|
||||
digitalWrite(SCK, LOW);
|
||||
digitalWrite(MOSI, LOW);
|
||||
pinMode(SCK, OUTPUT);
|
||||
pinMode(MOSI, OUTPUT);
|
||||
}
|
||||
|
||||
/** \brief Set SPI bit order.
|
||||
/** \brief Set up SPI for transmitting
|
||||
|
||||
Pepare the SPI interface for transmitting on or more bytes of
|
||||
commands and/or data.
|
||||
*/
|
||||
void MVSPIClass::packetBegin() {
|
||||
// Enable SPI mode
|
||||
SPCR |= _BV(SPE);
|
||||
|
||||
// Set SS low
|
||||
SSLOW;
|
||||
}
|
||||
|
||||
/** \brief End a SPI packet transmission
|
||||
|
||||
End a SPI packet transmission:
|
||||
- Wait for the last byte to finish being transmitted.
|
||||
- Set DC to command mode (even if already set that way, just in case).
|
||||
- Set SS high.
|
||||
- Disable SPI mode (causing SCK and MOSI to go low).
|
||||
*/
|
||||
void MVSPIClass::packetEnd() {
|
||||
while (!(SPSR & _BV(SPIF)))
|
||||
;
|
||||
DCLOW;
|
||||
SSHIGH;
|
||||
SPCR &= ~_BV(SPE);
|
||||
}
|
||||
|
||||
/** \brief Set SPI bit order.
|
||||
|
||||
Set SPI port bit order with LSBFIRST or MSBFIRST.
|
||||
*/
|
||||
@@ -1687,7 +1795,7 @@ size_t MicroView::write(uint8_t c) {
|
||||
|
||||
/** \brief Set SPI data mode.
|
||||
|
||||
Set the SPI daa mode: clock polarity and phase. mode - SPI_MODE0, SPI_MODE1, SPI_MODE2, SPI_MODE3.
|
||||
Set the SPI data mode: clock polarity and phase. mode - SPI_MODE0, SPI_MODE1, SPI_MODE2, SPI_MODE3.
|
||||
*/
|
||||
void MVSPIClass::setDataMode(uint8_t mode)
|
||||
{
|
||||
|
||||
73
MicroView.h
73
MicroView.h
@@ -24,13 +24,35 @@
|
||||
|
||||
#define swap(a, b) { uint8_t t = a; a = b; b = t; }
|
||||
|
||||
#define DC 8
|
||||
#define RESET 7
|
||||
#define OLEDPWR 4
|
||||
#define OLEDPWR 4 // 3.3V regulator enable
|
||||
|
||||
// SS, SCK, MOSI already defined by original pins_arduino.h
|
||||
//#define CS 10
|
||||
//#define SCK 13
|
||||
// Port and bit mappings for DC, RESET, SS
|
||||
// ** These are CPU dependent **
|
||||
#define DCPORT PORTB
|
||||
#define DCDDR DDRB
|
||||
#define DCBIT 0
|
||||
|
||||
#define RESETPORT PORTD
|
||||
#define RESETDDR DDRD
|
||||
#define RESETBIT 7
|
||||
|
||||
#define SSPORT PORTB
|
||||
#define SSDDR DDRB
|
||||
#define SSBIT 2
|
||||
|
||||
// Macros to quickly set DC, RESET, SS
|
||||
// A HIGH sets the signal to input mode with the internal pullup enabled
|
||||
#define DCHIGH ((DCPORT |= _BV(DCBIT)), (DCDDR &= ~_BV(DCBIT)))
|
||||
#define DCLOW ((DCPORT &= ~_BV(DCBIT)), (DCDDR |= _BV(DCBIT)))
|
||||
|
||||
#define RESETHIGH ((RESETPORT |= _BV(RESETBIT)), (RESETDDR &= ~_BV(RESETBIT)))
|
||||
#define RESETLOW ((RESETPORT &= ~_BV(RESETBIT)), (RESETDDR |= _BV(RESETBIT)))
|
||||
|
||||
#define SSHIGH ((SSPORT |= _BV(SSBIT)), (SSDDR &= ~_BV(SSBIT)))
|
||||
#define SSLOW ((SSPORT &= ~_BV(SSBIT)), (SSDDR |= _BV(SSBIT)))
|
||||
|
||||
// SCK, MOSI already defined by original pins_arduino.h
|
||||
//#define SCK 13
|
||||
//#define MOSI 11
|
||||
|
||||
#define BLACK 0
|
||||
@@ -38,6 +60,13 @@
|
||||
|
||||
#define LCDWIDTH 64
|
||||
#define LCDHEIGHT 48
|
||||
#define LCDPAGES (LCDHEIGHT / 8)
|
||||
#define LCDCOLUMNOFFSET 32 // Visible start column within SSD1306 controller memory
|
||||
|
||||
#define LCDTOTALWIDTH 128 // Full width of SSD1306 controller memory
|
||||
#define LCDTOTALHEIGHT 64 // Full height of SSD1306 controller memory
|
||||
#define LCDTOTALPAGES (LCDTOTALHEIGHT / 8)
|
||||
|
||||
#define FONTHEADERSIZE 6
|
||||
|
||||
#define NORM 0
|
||||
@@ -49,6 +78,8 @@
|
||||
#define WIDGETSTYLE0 0
|
||||
#define WIDGETSTYLE1 1
|
||||
#define WIDGETSTYLE2 2
|
||||
//Added for Vertical slider styles
|
||||
#define WIDGETSTYLE3 3
|
||||
|
||||
#define SETCONTRAST 0x81
|
||||
#define DISPLAYALLONRESUME 0xA4
|
||||
@@ -65,6 +96,10 @@
|
||||
#define SETMULTIPLEX 0xA8
|
||||
#define SETLOWCOLUMN 0x00
|
||||
#define SETHIGHCOLUMN 0x10
|
||||
#define SETPAGE 0xB0
|
||||
#define SETADDRESSMODE 0x20
|
||||
#define SETCOLUMNBOUNDS 0x21
|
||||
#define SETPAGEBOUNDS 0x22
|
||||
#define SETSTARTLINE 0x40
|
||||
#define MEMORYMODE 0x20
|
||||
#define COMSCANINC 0xC0
|
||||
@@ -109,6 +144,7 @@ class MicroView : public Print{
|
||||
public:
|
||||
MicroView(void) {};
|
||||
void begin(void);
|
||||
void end(void);
|
||||
|
||||
//#if ARDUINO >= 100
|
||||
|
||||
@@ -120,6 +156,8 @@ public:
|
||||
|
||||
// RAW LCD functions
|
||||
void command(uint8_t c);
|
||||
void command(uint8_t c1, uint8_t c2);
|
||||
void command(uint8_t c1, uint8_t c2, uint8_t c3);
|
||||
void data(uint8_t c);
|
||||
void setColumnAddress(uint8_t add);
|
||||
void setPageAddress(uint8_t add);
|
||||
@@ -178,10 +216,6 @@ public:
|
||||
void doCmd(uint8_t index);
|
||||
|
||||
private:
|
||||
//uint8_t cs;
|
||||
//volatile uint8_t *mosiport, *sckport;
|
||||
volatile uint8_t *ssport, *dcport, *ssreg, *dcreg; // use volatile because these are fixed location port address
|
||||
uint8_t mosipinmask, sckpinmask, sspinmask, dcpinmask;
|
||||
uint8_t foreColor,drawMode,fontWidth, fontHeight, fontType, fontStartChar, fontTotalChar, cursorX, cursorY;
|
||||
uint16_t fontMapWidth;
|
||||
//unsigned char *fontsPointer[TOTALFONTS];
|
||||
@@ -261,8 +295,17 @@ private:
|
||||
|
||||
class MVSPIClass {
|
||||
public:
|
||||
/** \brief Wait for SPI serial transfer complete. */
|
||||
inline static void wait();
|
||||
|
||||
/** \brief Transfer data byte via SPI port. */
|
||||
inline static byte transfer(byte _data);
|
||||
inline static void transfer(byte _data);
|
||||
|
||||
/** \brief Set up to begin a SPI packet transmit */
|
||||
static void packetBegin();
|
||||
|
||||
/** \brief End a SPI packet transmit */
|
||||
static void packetEnd();
|
||||
|
||||
// SPI Configuration methods
|
||||
|
||||
@@ -279,11 +322,13 @@ public:
|
||||
|
||||
extern MVSPIClass MVSPI;
|
||||
|
||||
byte MVSPIClass::transfer(byte _data) {
|
||||
SPDR = _data;
|
||||
void MVSPIClass::wait() {
|
||||
while (!(SPSR & _BV(SPIF)))
|
||||
;
|
||||
return SPDR;
|
||||
}
|
||||
|
||||
void MVSPIClass::transfer(byte _data) {
|
||||
SPDR = _data;
|
||||
}
|
||||
|
||||
void MVSPIClass::attachInterrupt() {
|
||||
|
||||
13
README.md
13
README.md
@@ -91,7 +91,18 @@ void loop() {
|
||||
</code></pre>
|
||||
|
||||
## History
|
||||
**v1.14b: 26th July 2014 by JP Liew
|
||||
**v1.16b: 3rd August 2014 by czetie**
|
||||
* added vertical slider widget
|
||||
|
||||
**v1.15b: 3rd August 2014 by Scott Allen**
|
||||
* improved lots of low level routines, Fast SPI
|
||||
* fixed some compilation warnings
|
||||
* reduced overdriving display inputs
|
||||
* added uVuew.end() to power off the display
|
||||
* improved speed of display() and clear() functions
|
||||
* fixed positionning of "3" on clock face
|
||||
|
||||
**v1.14b: 26th July 2014 by JP Liew**
|
||||
* added Learning Kit Circuit Sketch
|
||||
|
||||
**v1.13b: 13th June 2014 by JP Liew**
|
||||
|
||||
@@ -373,7 +373,7 @@ void loop() {
|
||||
uView.print(6);
|
||||
uView.setCursor(0,uView.getLCDHeight() /2-(uView.getFontHeight()/2));
|
||||
uView.print(9);
|
||||
uView.setCursor(uView.getLCDWidth()-uView.getFontWidth(),uView.getLCDWidth()/2-(uView.getFontHeight()/2));
|
||||
uView.setCursor(uView.getLCDWidth()-uView.getFontWidth(),uView.getLCDHeight()/2-(uView.getFontHeight()/2));
|
||||
uView.print(3);
|
||||
uView.display(); // display the memory buffer drawn
|
||||
|
||||
@@ -618,4 +618,4 @@ void loop() {
|
||||
uView.clear(PAGE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
43
examples/MicroViewVSlider/MicroViewVSlider.ino
Normal file
43
examples/MicroViewVSlider/MicroViewVSlider.ino
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
MicroView Arduino Library
|
||||
Copyright (C) 2014 GeekAmmo
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <MicroView.h>
|
||||
|
||||
MicroViewWidget *vWidget1, *vWidget2;
|
||||
|
||||
void setup() {
|
||||
uView.begin();
|
||||
uView.clear(PAGE);
|
||||
|
||||
vWidget1 = new MicroViewSlider(0, 0, 0, 255, WIDGETSTYLE2);
|
||||
vWidget2 = new MicroViewSlider(31, 0, 0, 255, WIDGETSTYLE3);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
for (int i=0;i<=255;i++) {
|
||||
vWidget1->setValue(i);
|
||||
vWidget2->setValue(255-i);
|
||||
uView.display();
|
||||
}
|
||||
|
||||
for(int i=255; i>=0;i--) {
|
||||
vWidget1->setValue(i);
|
||||
vWidget2->setValue(255-i);
|
||||
uView.display();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,5 +77,6 @@ ALL LITERAL1
|
||||
WIDGETSTYLE0 LITERAL1
|
||||
WIDGETSTYLE1 LITERAL1
|
||||
WIDGETSTYLE2 LITERAL1
|
||||
WIDGETSTYLE3 LITERAL1
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user