10 Commits

Author SHA1 Message Date
JP
fb8b9c4a43 added debug messages for doCmd() 2014-04-17 15:49:39 +10:00
JP
e6045dcfa1 added flipVertical and horizontal 2014-02-25 11:58:56 +11:00
JP
93beac25d5 added checkComm() function to communicate with host PC 2014-02-15 10:15:03 +11:00
JP
7fd29e3c92 added Serial command 2014-02-12 20:50:07 +11:00
JP
eaf0862bb5 added invert function, contrast function, changed scrollStop to scrollStop for consistency 2014-02-11 19:43:01 +11:00
JP
ec1c760c7c added round gauge widget 2014-02-08 20:34:28 +11:00
JP
684a5dc5c8 fixed Example 3 2014-02-07 14:15:49 +11:00
JP
8c12a660e6 added Example 3 2014-02-07 14:15:12 +11:00
JP
af4f0bea23 added Example 3 2014-02-07 14:13:35 +11:00
JP
7f15062e58 fixed Slider negative value not working 2014-02-07 14:05:52 +11:00
6 changed files with 958 additions and 177 deletions

View File

@@ -6,7 +6,7 @@
#undef PROGMEM
#define PROGMEM __attribute__((section(".progmem.data")))
// Add header of the fonts here. Remove as many as possible to get conserve FLASH memory.
// Add header of the fonts here. Remove as many as possible to conserve FLASH memory.
#include <font5x7.h>
#include <font8x16.h>
#include <fontlargenumber.h>
@@ -15,8 +15,13 @@
#include <space02.h>
#include <space03.h>
// Change the total fonts included
#define TOTALFONTS 7
#define recvLEN 100
char serInStr[recvLEN]; // TODO - need to fix a value so that this will not take up too much memory.
uint8_t serCmd[recvLEN];
// Add the font name as declared in the header file. Remove as many as possible to get conserve FLASH memory.
const unsigned char *MicroView::fontsPointer[]={
@@ -140,7 +145,6 @@ void MicroView::begin() {
command(DISPLAYALLONRESUME); // 0xA4
command(SEGREMAP | 0x1);
command(COMSCANDEC);
command(SETCOMPINS); // 0xDA
@@ -157,6 +161,7 @@ void MicroView::begin() {
command(DISPLAYON); //--turn on oled panel
clear(ALL); // Erase hardware memory inside the OLED controller to avoid random data in memory.
Serial.begin(115200);
}
void MicroView::command(uint8_t c) {
@@ -233,6 +238,18 @@ void MicroView::clear(uint8_t mode, uint8_t c) {
}
}
void MicroView::invert(boolean inv) {
if (inv)
command(INVERTDISPLAY);
else
command(NORMALDISPLAY);
}
void MicroView::contrast(uint8_t contrast) {
command(SETCONTRAST); // 0x81
command(contrast);
}
// This routine is to transfer the page buffer to the LCD controller's memory.
void MicroView::display(void) {
uint8_t i, j;
@@ -633,14 +650,14 @@ size_t MicroView::write(uint8_t c) {
}
void MicroView::stopScroll(void){
void MicroView::scrollStop(void){
command(DEACTIVATESCROLL);
}
void MicroView::scrollRight(uint8_t start, uint8_t stop){
if (stop<start) // stop must be larger or equal to start
return;
stopScroll(); // need to disable scrolling before starting to avoid memory corrupt
scrollStop(); // need to disable scrolling before starting to avoid memory corrupt
command(RIGHTHORIZONTALSCROLL);
command(0x00);
command(start);
@@ -650,149 +667,750 @@ size_t MicroView::write(uint8_t c) {
command(0xFF);
command(ACTIVATESCROLL);
}
MicroViewWidget::MicroViewWidget(uint8_t newx, uint8_t newy, int16_t min, int16_t max) {
setX(newx);
setY(newy);
value=0;
if (min>max) {
setMinValue(max);
setMaxValue(min);
void MicroView::flipVertical(boolean flip) {
if (flip) {
command(COMSCANINC);
}
else {
setMinValue(min);
setMaxValue(max);
command(COMSCANDEC);
}
setValue(min);
}
uint8_t MicroViewWidget::getX() { return x; }
uint8_t MicroViewWidget::getY() { return y; }
void MicroViewWidget::setX(uint8_t newx) { x = newx; }
void MicroViewWidget::setY(uint8_t newy) { y = newy; }
int16_t MicroViewWidget::getMinValue() { return minValue; }
int16_t MicroViewWidget::getMaxValue() { return maxValue; }
int16_t MicroViewWidget::getValue() { return value; }
void MicroViewWidget::setMinValue(int16_t min) { minValue=min; }
void MicroViewWidget::setMaxValue(int16_t max) { maxValue=max; }
void MicroViewWidget::setValue(int16_t val) {
if (val<=maxValue) {
value=val;
this->draw();
void MicroView::flipHorizontal(boolean flip) {
if (flip) {
command(SEGREMAP | 0x0);
}
else {
command(SEGREMAP | 0x1);
}
}
MicroViewSlider::MicroViewSlider(uint8_t newx, uint8_t newy, int16_t min, int16_t max):MicroViewWidget(newx, newy, min, max) {
totalTicks=40;
needFirstDraw=true;
prevValue=getMinValue();
}
void MicroViewSlider::draw() {
uint8_t offsetX, offsetY;
uint8_t tickPosition=0;
char strBuffer[5];
void MicroView::doCmd(uint8_t cmdCount) {
// decode command
switch (serCmd[0]) {
case CMD_CLEAR: {
if (cmdCount==1) {
Serial.print("clear ");
Serial.println(serCmd[1]);
clear(serCmd[1]);
} else if (cmdCount==2) {
Serial.print("clear ");
Serial.print(serCmd[1]);
Serial.print(" ");
Serial.println(serCmd[2]);
clear(serCmd[1], serCmd[2]);
}
break;
}
offsetX=getX();
offsetY=getY();
case CMD_INVERT: {
if (cmdCount==1) {
Serial.print("invert ");
Serial.println(serCmd[1]);
invert(serCmd[1]);
}
break;
}
case CMD_CONTRAST: {
if (cmdCount==1) {
Serial.print("contrast ");
Serial.println(serCmd[1]);
contrast(serCmd[1]);
}
break;
}
case CMD_DISPLAY: {
if (cmdCount==0) {
Serial.println("display");
display();
}
break;
}
case CMD_SETCURSOR: {
if (cmdCount==2) {
Serial.print("setCursor ");
Serial.print(serCmd[1]);
Serial.print(" ");
Serial.println(serCmd[2]);
setCursor(serCmd[1], serCmd[2]);
}
break;
}
case CMD_PIXEL: {
if (cmdCount==2) {
Serial.print("pixel ");
Serial.print(serCmd[1]);
Serial.print(" ");
Serial.println(serCmd[2]);
pixel(serCmd[1],serCmd[2]);
display();
} else if (cmdCount=4) {
Serial.print("pixel ");
Serial.print(serCmd[1]);
Serial.print(" ");
Serial.println(serCmd[2]);
Serial.print(" ");
Serial.print(serCmd[3]);
Serial.print(" ");
Serial.println(serCmd[4]);
pixel(serCmd[1],serCmd[2],serCmd[3],serCmd[4]);
display();
}
break;
}
case CMD_LINE: {
if (cmdCount==4) {
Serial.print("line ");
Serial.print(serCmd[1]);
Serial.print(" ");
Serial.print(serCmd[2]);
Serial.print(" ");
Serial.print(serCmd[3]);
Serial.print(" ");
Serial.println(serCmd[4]);
line(serCmd[1],serCmd[2],serCmd[3],serCmd[4]);
display();
} else if (cmdCount==6) {
Serial.print("line ");
Serial.print(serCmd[1]);
Serial.print(" ");
Serial.print(serCmd[2]);
Serial.print(" ");
Serial.print(serCmd[3]);
Serial.print(" ");
Serial.print(serCmd[4]);
Serial.print(" ");
Serial.print(serCmd[5]);
Serial.print(" ");
Serial.println(serCmd[6]);
line(serCmd[1],serCmd[2],serCmd[3],serCmd[4],serCmd[5],serCmd[6]);
display();
}
break;
}
// Draw major tickers
for (uint8_t i=0; i<5;i++) {
uView.lineV(offsetX+1+(i*10), offsetY+3, 5);
case CMD_LINEH: {
if (cmdCount==3) {
Serial.print("lineH ");
Serial.print(serCmd[1]);
Serial.print(" ");
Serial.print(serCmd[2]);
Serial.print(" ");
Serial.println(serCmd[3]);
lineH(serCmd[1], serCmd[2], serCmd[3]);
display();
} else if (cmdCount==5) {
Serial.print("lineH ");
Serial.print(serCmd[1]);
Serial.print(" ");
Serial.print(serCmd[2]);
Serial.print(" ");
Serial.print(serCmd[3]);
Serial.print(" ");
Serial.print(serCmd[4]);
Serial.print(" ");
Serial.println(serCmd[5]);
lineH(serCmd[1], serCmd[2], serCmd[3], serCmd[4], serCmd[5]);
display();
}
break;
}
// Draw minor tickers
for (uint8_t i=0; i<4;i++) {
uView.lineV(offsetX+3+(i*2), offsetY+5, 3);
case CMD_LINEV: {
if (cmdCount==3) {
Serial.print("lineH ");
Serial.print(serCmd[1]);
Serial.print(" ");
Serial.print(serCmd[2]);
Serial.print(" ");
Serial.println(serCmd[3]);
lineV(serCmd[1], serCmd[2], serCmd[3]);
display();
} else if (cmdCount==5) {
Serial.print("lineH ");
Serial.print(serCmd[1]);
Serial.print(" ");
Serial.print(serCmd[2]);
Serial.print(" ");
Serial.print(serCmd[3]);
Serial.print(" ");
Serial.print(serCmd[4]);
Serial.print(" ");
Serial.println(serCmd[5]);
lineV(serCmd[1], serCmd[2], serCmd[3], serCmd[4], serCmd[5]);
display();
}
break;
}
for (uint8_t i=0; i<4;i++) {
uView.lineV(offsetX+13+(i*2), offsetY+5, 3);
case CMD_RECT: {
if (cmdCount==4) {
Serial.print("rect ");
Serial.print(serCmd[1]);
Serial.print(" ");
Serial.print(serCmd[2]);
Serial.print(" ");
Serial.print(serCmd[3]);
Serial.print(" ");
Serial.println(serCmd[4]);
rect(serCmd[1], serCmd[2], serCmd[3], serCmd[4]);
display();
} else if (cmdCount==6) {
Serial.print("rect ");
Serial.print(serCmd[1]);
Serial.print(" ");
Serial.print(serCmd[2]);
Serial.print(" ");
Serial.print(serCmd[3]);
Serial.print(" ");
Serial.print(serCmd[4]);
Serial.print(" ");
Serial.print(serCmd[5]);
Serial.print(" ");
Serial.println(serCmd[6]);
rect(serCmd[1], serCmd[2], serCmd[3], serCmd[4], serCmd[5], serCmd[6]);
display();
}
break;
}
for (uint8_t i=0; i<4;i++) {
uView.lineV(offsetX+23+(i*2), offsetY+5, 3);
case CMD_RECTFILL: {
if (cmdCount==4) {
Serial.print("rectFill ");
Serial.print(serCmd[1]);
Serial.print(" ");
Serial.print(serCmd[2]);
Serial.print(" ");
Serial.print(serCmd[3]);
Serial.print(" ");
Serial.println(serCmd[4]);
rectFill(serCmd[1], serCmd[2], serCmd[3], serCmd[4]);
display();
} else if (cmdCount==6) {
Serial.print("rectFill ");
Serial.print(serCmd[1]);
Serial.print(" ");
Serial.print(serCmd[2]);
Serial.print(" ");
Serial.print(serCmd[3]);
Serial.print(" ");
Serial.print(serCmd[4]);
Serial.print(" ");
Serial.print(serCmd[5]);
Serial.print(" ");
Serial.println(serCmd[6]);
rectFill(serCmd[1], serCmd[2], serCmd[3], serCmd[4], serCmd[5], serCmd[6]);
display();
}
break;
}
case CMD_CIRCLE: {
if (cmdCount==3) {
Serial.print("circle ");
Serial.print(serCmd[1]);
Serial.print(" ");
Serial.print(serCmd[2]);
Serial.print(" ");
Serial.println(serCmd[3]);
circle(serCmd[1], serCmd[2], serCmd[3]);
display();
} else if (cmdCount==5) {
Serial.print("circle ");
Serial.print(serCmd[1]);
Serial.print(" ");
Serial.print(serCmd[2]);
Serial.print(" ");
Serial.print(serCmd[3]);
Serial.print(" ");
Serial.print(serCmd[4]);
Serial.print(" ");
Serial.println(serCmd[5]);
circle(serCmd[1], serCmd[2], serCmd[3], serCmd[4], serCmd[5]);
display();
}
break;
}
case CMD_CIRCLEFILL: {
if (cmdCount==3) {
Serial.print("circle ");
Serial.print(serCmd[1]);
Serial.print(" ");
Serial.print(serCmd[2]);
Serial.print(" ");
Serial.println(serCmd[3]);
circleFill(serCmd[1], serCmd[2], serCmd[3]);
display();
} else if (cmdCount==5) {
Serial.print("circle ");
Serial.print(serCmd[1]);
Serial.print(" ");
Serial.print(serCmd[2]);
Serial.print(" ");
Serial.print(serCmd[3]);
Serial.print(" ");
Serial.print(serCmd[4]);
Serial.print(" ");
Serial.println(serCmd[5]);
circleFill(serCmd[1], serCmd[2], serCmd[3], serCmd[4], serCmd[5]);
display();
}
break;
}
case CMD_DRAWCHAR: {
if (cmdCount==3) {
Serial.print("drawChar ");
Serial.print(serCmd[1]);
Serial.print(" ");
Serial.print(serCmd[2]);
Serial.print(" ");
Serial.println(serCmd[3]);
drawChar(serCmd[1], serCmd[2], serCmd[3]);
display();
} else if (cmdCount==5) {
Serial.print("drawChar ");
Serial.print(serCmd[1]);
Serial.print(" ");
Serial.print(serCmd[2]);
Serial.print(" ");
Serial.print(serCmd[3]);
Serial.print(" ");
Serial.print(serCmd[4]);
Serial.print(" ");
Serial.println(serCmd[5]);
drawChar(serCmd[1], serCmd[2], serCmd[3], serCmd[4], serCmd[5]);
display();
}
break;
}
case CMD_DRAWBITMAP: {
// TODO
break;
}
case CMD_GETLCDWIDTH: {
if (cmdCount==0) {
Serial.print("LCDWidth=");
Serial.println(getLCDWidth());
}
break;
}
case CMD_GETLCDHEIGHT: {
if (cmdCount==0) {
Serial.print("LCDHeight=");
Serial.println(getLCDHeight());
}
break;
}
case CMD_SETCOLOR: {
if (cmdCount==1) {
Serial.print("setColor ");
Serial.println(serCmd[1]);
setColor(serCmd[1]);
}
break;
}
case CMD_SETDRAWMODE: {
if (cmdCount==1) {
Serial.print("drawMode ");
Serial.println(serCmd[1]);
setDrawMode(serCmd[1]);
}
break;
}
default:
break;
}
}
void MicroView::checkComm(void) {
int count = readSerial();
char *result;
uint8_t index=0;
int temp;
if (count>0) {
// process Serial data
result=strtok(serInStr,",");
if (result !=NULL) {
temp=atoi(result);
serCmd[index]=(uint8_t)temp & 0xff; // we only need 8 bit number
index++;
for (uint8_t i;i<recvLEN;i++) {
result=strtok(NULL,",");
if (result != NULL) {
temp=atoi(result);
serCmd[index]=(uint8_t)temp & 0xff; // we only need 8 bit number
index++;
}
else {
break;
}
}
/*
// debug output
Serial.print("command received=");
Serial.println(index);
for (uint8_t i=0;i<index;i++) {
Serial.println(serCmd[i]);
}
*/
}
doCmd(index-1); // index-1 is the total parameters count of a command
}
}
int MicroView::readSerial(void)
{
int i=0;
if(!Serial.available())
return -1;
while (Serial.available()>0)
{
if( i < recvLEN)
{
serInStr[i++] = Serial.read();
delay(2);
}
else
break;
}
serInStr[i]='\0';
return i;
}
// -------------------------------------------------------------------------------------
// MicroViewWidget Class - start
// -------------------------------------------------------------------------------------
MicroViewWidget::MicroViewWidget(uint8_t newx, uint8_t newy, int16_t min, int16_t max) {
setX(newx);
setY(newy);
value=0;
setMinValue(min);
setMaxValue(max);
}
uint8_t MicroViewWidget::getX() { return x; }
uint8_t MicroViewWidget::getY() { return y; }
void MicroViewWidget::setX(uint8_t newx) { x = newx; }
void MicroViewWidget::setY(uint8_t newy) { y = newy; }
int16_t MicroViewWidget::getMinValue() { return minValue; }
int16_t MicroViewWidget::getMaxValue() { return maxValue; }
int16_t MicroViewWidget::getValue() { return value; }
void MicroViewWidget::setMinValue(int16_t min) { minValue=min; }
void MicroViewWidget::setMaxValue(int16_t max) { maxValue=max; }
void MicroViewWidget::setValue(int16_t val) {
if ((val<=maxValue) && (val>=minValue)){
value=val;
this->draw();
}
}
// -------------------------------------------------------------------------------------
// MicroViewWidget Class - end
// -------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------
// Slider Widget - start
// -------------------------------------------------------------------------------------
MicroViewSlider::MicroViewSlider(uint8_t newx, uint8_t newy, int16_t min, int16_t max):MicroViewWidget(newx, newy, min, max) {
style=0;
totalTicks=30;
needFirstDraw=true;
prevValue=getMinValue();
drawFace();
draw();
}
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 {
style=1;
totalTicks=60;
}
needFirstDraw=true;
prevValue=getMinValue();
drawFace();
draw();
}
void MicroViewSlider::drawFace() {
uint8_t offsetX, offsetY, majorLine;
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 (needFirstDraw) {
uView.lineH(offsetX,offsetY, 3, WHITE,XOR);
uView.pixel(offsetX+1,offsetY+1, WHITE,XOR);
needFirstDraw=false;
if (style>0) {
for (uint8_t i=0; i<4;i++) {
uView.lineV(offsetX+43+(i*2), offsetY+5, 3);
}
for (uint8_t i=0; i<4;i++) {
uView.lineV(offsetX+53+(i*2), offsetY+5, 3);
}
}
else {
// Draw previous pointer in XOR mode to erase it
tickPosition= (((float)prevValue/(float)(getMaxValue()-getMinValue()))*totalTicks);
uView.lineH(offsetX+tickPosition,offsetY, 3, WHITE, XOR);
uView.pixel(offsetX+1+tickPosition,offsetY+1, WHITE, XOR);
// Draw current pointer
tickPosition= (((float)getValue()/(float)(getMaxValue()-getMinValue()))*totalTicks);
uView.lineH(offsetX+tickPosition,offsetY, 3, WHITE, XOR);
uView.pixel(offsetX+1+tickPosition,offsetY+1, WHITE, XOR);
}
}
}
void MicroViewSlider::draw() {
uint8_t offsetX, offsetY;
uint8_t tickPosition=0;
char strBuffer[5];
offsetX=getX();
offsetY=getY();
// Draw value
uView.setCursor(offsetX+44,offsetY);
sprintf(strBuffer,"%3d", getValue()); // we need to force only 3 digit or it will go over the display.
uView.print(strBuffer);
if (needFirstDraw) {
uView.lineH(offsetX+tickPosition,offsetY, 3, WHITE, XOR);
uView.pixel(offsetX+1+tickPosition,offsetY+1, 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);
// 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);
sprintf(strBuffer,"%4d", getValue()); // we need to force 4 digit so that blank space will cover larger value
prevValue=getValue();
}
void SPIClass::begin() {
// Draw value
if(style>0)
uView.setCursor(offsetX,offsetY+10);
else
uView.setCursor(offsetX+34,offsetY+1);
uView.print(strBuffer);
}
// Set SS to high so a connected chip will be "deselected" by default
digitalWrite(SS, HIGH);
// -------------------------------------------------------------------------------------
// Slider Widget - end
// -------------------------------------------------------------------------------------
// 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);
// -------------------------------------------------------------------------------------
// Gauge Widget - start
// -------------------------------------------------------------------------------------
// 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);
MicroViewGauge::MicroViewGauge(uint8_t newx, uint8_t newy, int16_t min, int16_t max):MicroViewWidget(newx, newy, min, max) {
style=0;
radius=15;
needFirstDraw=true;
prevValue=getMinValue();
drawFace();
draw();
}
// 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
pinMode(SCK, OUTPUT);
pinMode(MOSI, OUTPUT);
MicroViewGauge::MicroViewGauge(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;
radius=15;
}
void SPIClass::end() {
SPCR &= ~_BV(SPE);
else {
style=1;
radius=23;
}
needFirstDraw=true;
prevValue=getMinValue();
drawFace();
draw();
}
void SPIClass::setBitOrder(uint8_t bitOrder)
{
if(bitOrder == LSBFIRST) {
SPCR |= _BV(DORD);
} else {
SPCR &= ~(_BV(DORD));
void MicroViewGauge::drawFace() {
uint8_t offsetX, offsetY, majorLine;
float degreeSec, fromSecX, fromSecY, toSecX, toSecY;
offsetX=getX();
offsetY=getY();
uView.circle(offsetX,offsetY,radius);
for (int i=150;i<=390;i+=30) { // Major tick from 150 degree to 390 degree
degreeSec=i*(PI/180);
fromSecX = cos(degreeSec) * (radius / 1.5);
fromSecY = sin(degreeSec) * (radius / 1.5);
toSecX = cos(degreeSec) * (radius / 1);
toSecY = sin(degreeSec) * (radius / 1);
uView.line(1+offsetX+fromSecX,1+offsetY+fromSecY,1+offsetX+toSecX,1+offsetY+toSecY);
}
if(radius>15) {
for (int i=150;i<=390;i+=15) { // Minor tick from 150 degree to 390 degree
degreeSec=i*(PI/180);
fromSecX = cos(degreeSec) * (radius / 1.3);
fromSecY = sin(degreeSec) * (radius / 1.3);
toSecX = cos(degreeSec) * (radius / 1);
toSecY = sin(degreeSec) * (radius / 1);
uView.line(1+offsetX+fromSecX,1+offsetY+fromSecY,1+offsetX+toSecX,1+offsetY+toSecY);
}
}
}
void SPIClass::setDataMode(uint8_t mode)
{
SPCR = (SPCR & ~SPI_MODE_MASK) | mode;
void MicroViewGauge::draw() {
uint8_t offsetX, offsetY;
uint8_t tickPosition=0;
float degreeSec, fromSecX, fromSecY, toSecX, toSecY;
char strBuffer[5];
offsetX=getX();
offsetY=getY();
if (needFirstDraw) {
degreeSec = (((float)(prevValue-getMinValue())/(float)(getMaxValue()-getMinValue()))*240); // total 240 degree in the widget
degreeSec = (degreeSec+150) * (PI/180); // 150 degree starting point
toSecX = cos(degreeSec) * (radius / 1.2);
toSecY = sin(degreeSec) * (radius / 1.2);
uView.line(offsetX,offsetY,1+offsetX+toSecX,1+offsetY+toSecY, 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
degreeSec = (((float)(prevValue-getMinValue())/(float)(getMaxValue()-getMinValue()))*240); // total 240 degree in the widget
degreeSec = (degreeSec+150) * (PI/180);
toSecX = cos(degreeSec) * (radius / 1.2);
toSecY = sin(degreeSec) * (radius / 1.2);
uView.line(offsetX,offsetY,1+offsetX+toSecX,1+offsetY+toSecY, WHITE,XOR);
degreeSec = (((float)(getValue()-getMinValue())/(float)(getMaxValue()-getMinValue()))*240); // total 240 degree in the widget
degreeSec = (degreeSec+150) * (PI/180); // 150 degree starting point
toSecX = cos(degreeSec) * (radius / 1.2);
toSecY = sin(degreeSec) * (radius / 1.2);
uView.line(offsetX,offsetY,1+offsetX+toSecX,1+offsetY+toSecY, WHITE,XOR);
sprintf(strBuffer,"%4d", getValue()); // we need to force 4 digit so that blank space will cover larger value
prevValue=getValue();
}
void SPIClass::setClockDivider(uint8_t rate)
{
SPCR = (SPCR & ~SPI_CLOCK_MASK) | (rate & SPI_CLOCK_MASK);
SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((rate >> 2) & SPI_2XCLOCK_MASK);
// Draw value
if(style>0)
uView.setCursor(offsetX-10,offsetY+10);
else
uView.setCursor(offsetX-11,offsetY+11);
uView.print(strBuffer);
}
// -------------------------------------------------------------------------------------
// Slider Widget - end
// -------------------------------------------------------------------------------------
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);
// 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);
// 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
pinMode(SCK, OUTPUT);
pinMode(MOSI, OUTPUT);
}
void MVSPIClass::end() {
SPCR &= ~_BV(SPE);
}
void MVSPIClass::setBitOrder(uint8_t bitOrder)
{
if(bitOrder == LSBFIRST) {
SPCR |= _BV(DORD);
} else {
SPCR &= ~(_BV(DORD));
}
}
SPIClass MVSPI;
MicroView uView;
void MVSPIClass::setDataMode(uint8_t mode)
{
SPCR = (SPCR & ~SPI_MODE_MASK) | mode;
}
void MVSPIClass::setClockDivider(uint8_t rate)
{
SPCR = (SPCR & ~SPI_CLOCK_MASK) | (rate & SPI_CLOCK_MASK);
SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((rate >> 2) & SPI_2XCLOCK_MASK);
}
MVSPIClass MVSPI;
MicroView uView;

View File

@@ -8,10 +8,11 @@
#define swap(a, b) { uint8_t t = a; a = b; b = t; }
#define DC 8
#define RESET 12
// SS, SCK, MOSI already defined by original SPI.h
//#define CS 10
//#define SCK 13
//#define MOSI 11
#define RESET 12
//#define CS 10
#define BLACK 0
#define WHITE 1
@@ -26,6 +27,10 @@
#define PAGE 0
#define ALL 1
#define WIDGETSTYLE0 0
#define WIDGETSTYLE1 1
#define WIDGETSTYLE2 2
#define SETCONTRAST 0x81
#define DISPLAYALLONRESUME 0xA4
#define DISPLAYALLON 0xA5
@@ -59,6 +64,28 @@
#define VERTICALRIGHTHORIZONTALSCROLL 0x29
#define VERTICALLEFTHORIZONTALSCROLL 0x2A
typedef enum CMD {
CMD_CLEAR, //0
CMD_INVERT, //1
CMD_CONTRAST, //2
CMD_DISPLAY, //3
CMD_SETCURSOR, //4
CMD_PIXEL, //5
CMD_LINE, //6
CMD_LINEH, //7
CMD_LINEV, //8
CMD_RECT, //9
CMD_RECTFILL, //10
CMD_CIRCLE, //11
CMD_CIRCLEFILL, //12
CMD_DRAWCHAR, //13
CMD_DRAWBITMAP, //14
CMD_GETLCDWIDTH, //15
CMD_GETLCDHEIGHT, //16
CMD_SETCOLOR, //17
CMD_SETDRAWMODE //18
} commCommand_t;
class MicroView : public Print{
public:
MicroView(void) {};
@@ -76,10 +103,11 @@ public:
void setColumnAddress(uint8_t add);
void setPageAddress(uint8_t add);
// LCD Draw functions
// LCD Draw functions
void clear(uint8_t mode);
void clear(uint8_t mode, uint8_t c);
void invert(uint8_t i);
void invert(boolean inv);
void contrast(uint8_t contrast);
void display(void);
void setCursor(uint8_t x, uint8_t y);
void pixel(uint8_t x, uint8_t y);
@@ -120,7 +148,13 @@ public:
void scrollLeft(uint8_t start, uint8_t stop);
void scrollVertRight(uint8_t start, uint8_t stop);
void scrollVertLeft(uint8_t start, uint8_t stop);
void stopScroll(void);
void scrollStop(void);
void flipVertical(boolean flip);
void flipHorizontal(boolean flip);
// Communication
void checkComm(void);
void doCmd(uint8_t index);
private:
//uint8_t cs;
@@ -130,6 +164,8 @@ private:
uint16_t fontMapWidth;
//unsigned char *fontsPointer[TOTALFONTS];
static const unsigned char *fontsPointer[];
int readSerial(void);
};
class MicroViewWidget {
@@ -147,6 +183,8 @@ public:
void setMinValue(int16_t max);
void setValue(int16_t val);
virtual void draw(){};
virtual void drawFace(){};
private:
uint8_t x;
uint8_t y;
@@ -158,13 +196,26 @@ private:
class MicroViewSlider: public MicroViewWidget{
public:
MicroViewSlider(uint8_t newx, uint8_t newy, int16_t min, int16_t max);
MicroViewSlider(uint8_t newx, uint8_t newy, int16_t min, int16_t max, uint8_t sty);
void draw();
void drawFace();
private:
uint8_t totalTicks;
uint8_t totalTicks, style;
bool needFirstDraw;
int16_t prevValue;
};
class MicroViewGauge: public MicroViewWidget{
public:
MicroViewGauge(uint8_t newx, uint8_t newy, int16_t min, int16_t max);
MicroViewGauge(uint8_t newx, uint8_t newy, int16_t min, int16_t max, uint8_t sty);
void draw();
void drawFace();
private:
uint8_t radius, style;
bool needFirstDraw;
int16_t prevValue;
};
#define SPI_CLOCK_DIV4 0x00
#define SPI_CLOCK_DIV16 0x01
@@ -184,7 +235,7 @@ private:
#define SPI_CLOCK_MASK 0x03 // SPR1 = bit 1, SPR0 = bit 0 on SPCR
#define SPI_2XCLOCK_MASK 0x01 // SPI2X = bit 0 on SPSR
class SPIClass {
class MVSPIClass {
public:
inline static byte transfer(byte _data);
@@ -201,20 +252,20 @@ public:
static void setClockDivider(uint8_t);
};
extern SPIClass MVSPI;
extern MVSPIClass MVSPI;
byte SPIClass::transfer(byte _data) {
byte MVSPIClass::transfer(byte _data) {
SPDR = _data;
while (!(SPSR & _BV(SPIF)))
;
return SPDR;
}
void SPIClass::attachInterrupt() {
void MVSPIClass::attachInterrupt() {
SPCR |= _BV(SPIE);
}
void SPIClass::detachInterrupt() {
void MVSPIClass::detachInterrupt() {
SPCR &= ~_BV(SPIE);
}

View File

@@ -16,13 +16,27 @@ Arduino library for MicroView.
2. Start Arduino IDE.
3. MicroView example is located at, File--->Example--->MicroView--->MicroViewDemo
### Example
### Example 1 - Hello World!
<pre><code>
#include &lt;MicroView.h&gt;
void setup() {
uView.begin();
uView.clear(PAGE); // clear the page buffer
}
void loop() {
uView.print("HelloWorld");
uView.display(); // display current page buffer
}
</code></pre>
### Example 2 - Basic Drawing
<pre><code>
#include &lt;MicroView.h&gt;
void setup() {
uView.begin();
uView.clear(PAGE); // clear the page buffer
}
void loop() {
@@ -32,12 +46,67 @@ void loop() {
uView.pixel(50,5);
uView.setCursor(0,40);
uView.print(" MicroView");
uView.display(); // display current page buffer
uView.display(); // display current page buffer
}
</code></pre>
### Example 3 - Widgets
<pre><code>
#include &lt;MicroView.h&gt;
MicroViewWidget *widget,*widget2;
void setup() {
uView.begin();
uView.clear(PAGE);
widget= new MicroViewGauge(32,30,0,100); // draw Gauge widget at x=32,y=30,min=0, max=100
widget2= new MicroViewSlider(0,0,0,100); // draw Slider widget at x=0,y=0,min=0, max=100
}
void loop() {
for(int i=0; i&lt;=100;i++) {
widget->setValue(i); // give a value to widget
widget2->setValue(i);
uView.display(); // display current page buffer
}
}
</code></pre>
### Example 4 - Communication
<pre><code>
#include &lt;MicroView.h&gt;
void setup() {
uView.begin();
uView.clear(PAGE);
}
void loop() {
uView.checkComm();
}
</code></pre>
## History
**v1.05b: 6th February by JP Liew**
**v1.09b: 17th April 2014 by JP Liew**
* changed verticalFlip() to flipVertical() and horizontalFlip() to flipHorizontal() for consistency
* added debug messages for doCmd()
**v1.08b: 18th February 2014 by JP Liew**
* added verticalFlip(), horizontalFlip()
**v1.07b: 15th February 2014 by JP Liew**
* changed function name stopScroll to scrollStop for consistency
* added contrast function
* added invert function
* added KEYWORD to keywords.txt
* added checkComm() function to communicate with host PC
**v1.06b: 9th February 2014 by JP Liew**
* fixed Slider negative value not working
* added round Gauge widget
* changed Example 3 to show round Gauge
**v1.05b: 6th February 2014 by JP Liew**
* changed MICROVIEW class name to MicroView
* created MICROVIEWWIDGET class
* added routines to draw widget
@@ -45,7 +114,6 @@ void loop() {
* merged MicroViewWidget into MicroView
* merged SPI.h into MicroView
**v1.04b: 3rd February 2014 by JP Liew**
* declared permanent uView variable.
* cleaned code and added some remarks.
@@ -63,5 +131,4 @@ void loop() {
* added analog clock demo.
**v1.00b: 30th January 2014 by JP Liew**
* Initial commit. Beta with minor bugs.
* Initial commit. Beta with minor bugs.

View File

@@ -1,18 +1,17 @@
#include <MicroView.h>
#include <Time.h>
//#define PI 3.141592654
#define clocksize 24
uint8_t onDelay=5; // This is the on delay in milliseconds, if there is no on delay, the erase will be too fast to clean up the screen.
uint8_t onDelay=5; // this is the on delay in milliseconds, if there is no on delay, the erase will be too fast to clean up the screen.
void setup() {
uView.begin(); // Begin of MicroView
uView.clear(ALL); // Erase hardware memory inside the OLED controller
uView.display(); // Display the content in the buffer memory, by default it is the MicroView logo
uView.begin(); // begin of MicroView
uView.clear(ALL); // erase hardware memory inside the OLED controller
uView.display(); // display the content in the buffer memory, by default it is the MicroView logo
setTime(10,10,01,17,1,2014);
delay(500);
uView.clear(PAGE); // Erase the memory buffer, when next uView.display() is called, the OLED will be cleared.
uView.clear(PAGE); // erase the memory buffer, when next uView.display() is called, the OLED will be cleared.
}
void loop() {
@@ -261,8 +260,6 @@ void loop() {
}
}
uView.clear(PAGE);
}

View File

@@ -1,39 +1,30 @@
#include <SPI.h>
#include <MicroView.h>
MicroViewWidget *widget[4];
void setup() {
widget[0] = new MicroViewSlider(0,0,0,100);
widget[1] = new MicroViewSlider(0,10,0,150);
widget[2] = new MicroViewSlider(0,20,0,50);
widget[3] = new MicroViewSlider(0,30,0,200);
Serial.begin(115200);
Serial.println("start");
uView.begin();
uView.clear(PAGE);
widget[0]->draw();
widget[1]->draw();
widget[2]->draw();
widget[3]->draw();
}
void loop() {
for (int i=0;i<101;i++) {
widget[0]->setValue(i);
widget[1]->setValue(100-i);
widget[2]->setValue(i);
widget[3]->setValue(100-i);
uView.display();
}
for(int i=100; i>-1;i--) {
widget[0]->setValue(i);
widget[1]->setValue(100-i);
widget[2]->setValue(i);
widget[3]->setValue(100-i);
uView.display();
}
#include <MicroView.h>
MicroViewWidget *widget[4]; // declaring an array of 4 MicroViewWidget
void setup() {
uView.begin(); // init and start MicroView
uView.clear(PAGE); // erase the memory buffer, when next uView.display() is called, the OLED will be cleared.
widget[0] = new MicroViewSlider(0,0,0,100); // declare widget0 as a Slider at x=0, y=0, min=0, max=100
widget[1] = new MicroViewSlider(0,10,0,150); // declare widget0 as a Slider at x=0, y=10, min=0, max=150
widget[2] = new MicroViewSlider(0,20,0,50); // declare widget0 as a Slider at x=0, y=20, min=0, max=50
widget[3] = new MicroViewSlider(0,30,0,200); // declare widget0 as a Slider at x=0, y=30, min=0, max=200
}
void loop() {
for (int i=0;i<=100;i++) {
widget[0]->setValue(i); // set value i to widget0
widget[1]->setValue(100-i);
widget[2]->setValue(i);
widget[3]->setValue(100-i);
uView.display();
}
for(int i=100; i>=0;i--) {
widget[0]->setValue(i);
widget[1]->setValue(100-i);
widget[2]->setValue(i);
widget[3]->setValue(100-i);
uView.display();
}
}

View File

@@ -7,18 +7,75 @@
#######################################
MICROVIEW KEYWORD1
uView KEYWORD1
MicroViewWidget KEYWORD1
MicroViewSlider KEYWORD1
MicroViewGauge KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
begin KEYWORD2
invert KEYWORD2
clear KEYWORD2
home KEYWORD2
invert KEYWORD2
contrast KEYWORD2
display KEYWORD2
setCursor KEYWORD2
pixel KEYWORD2
line KEYWORD2
lineH KEYWORD2
lineV KEYWORD2
rect KEYWORD2
rectFill KEYWORD2
circle KEYWORD2
circleFill KEYWORD2
drawChar KEYWORD2
getLCDWidth KEYWORD2
getLCDHeight KEYWORD2
setColor KEYWORD2
setDrawMode KEYWORD2
getFontWidth KEYWORD2
getFontHeight KEYWORD2
getTotalFonts KEYWORD2
getFontType KEYWORD2
setFontType KEYWORD2
getFontStartChar KEYWORD2
getFontTotalChar KEYWORD2
scrollRight KEYWORD2
scrollLeft KEYWORD2
scrollVertRight KEYWORD2
scrollVertLeft KEYWORD2
scrollStop KEYWORD2
flipVertical KEYWORD2
flipHorizontal KEYWORD2
getX KEYWORD2
getY KEYWORD2
setX KEYWORD2
setY KEYWORD2
getMinValue KEYWORD2
getMaxValue KEYWORD2
setMaxValue KEYWORD2
setMinValue KEYWORD2
setValue KEYWORD2
draw KEYWORD2
drawFace KEYWORD2
checkComm KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################
BLACK LITERAL1
WHITE LITERAL1
NORM LITERAL1
XOR LITERAL1
PAGE LITERAL1
ALL LITERAL1
WIDGETSTYLE0 LITERAL1
WIDGETSTYLE1 LITERAL1
WIDGETSTYLE2 LITERAL1