A general demonstration color etch-a-sketch program using the QVGA TFT with HX8347D controller, Orange Board. Saves touchscreen calibaration data saved in tft.ini. Creates /local/tft.ini if missing. Also included is an Ethernet NTP client to update the RTC. Assumes all other Orange Board devices attached: Text LCD, SDHC Flash, Ethernet.
Dependencies: EthernetNetIf TextLCD mbed
main.cpp
- Committer:
- loopsva
- Date:
- 2011-08-01
- Revision:
- 0:e065ca40f28a
File content as of revision 0:e065ca40f28a:
/* Rev Date Changes: ------------------------------------------------------------------------------------------------------------------------------------------ 100 7/19/11 - initial offering 101 7/25/11 - Adding RTC display-only functions. No provisions for setting the clock - Added red "clear_drawing" box to TFT - Added multi-color "change_pen_color" box - Added blue, pen_fattness circle (1-8) - Added "orange" color to pen_color selection - Added hidden system_reset function w/pen touch near "TFT" text 102 7/26/11 - Added EthernetNetIF and TinySNTP for updating RTC over Ethernet - Added a color choice palette after reset. Palette goes away after clear_screen 103 7/28/11 - Expqanded NTP service to two possible NTP servers. In and IP address, the other named - Added tube symbol for display - Modified the start-up splash screen 104 7/28/11 - Made tube display indepentent of rotation - Added more NTP server options ------------------------------------------------------------------------------------------------------------------------------------------ Known issues: ------------------------------------------------------------------------------------------------------------------------------------------ */ int revision = 104; // revision of this code #include "mbed.h" #include "SDHCFileSystem.h" // MUST be before EthernetNetIf.h or compile error occurs!!!! #include "adc.h" #include "EthernetNetIf.h" #include "TinySNTP.h" #include "TextLCD.h" #include "SPI_TFT.h" #include "Arial12x12.h" #include "Arial24x23.h" #include "Arial28x28.h" #include "font_big.h" #include "Courier10x13-12B.h" // kb modified font created by GLCD_Font_Creator.1.20.exe #include "Verdana22x21-16.h" // kb modified font created by GLCD_Font_Creator.1.20.exe #include "BookAntiqua19x19-14.h" // kb modified font created by GLCD_Font_Creator.1.20.exe #include "touch_tft.h" #define DEFAULTHOSTNAME "mbed-c3p1" char *hostname = DEFAULTHOSTNAME; //#define RTCCOLOR "Red" //char *JunkText = RTCCOLOR; //char *RtcColor = RTCCOLOR; #define SAMPLE_RATE 150000 #define CLS "\033[2J" extern "C" void mbed_reset(); #define Orange 0xF9E0 /*--------------------------------------------------------------------------------------------------------------------------------------*/ //I/O Pin Definitions LocalFileSystem local("local"); PwmOut led1(LED1, "led1"); DigitalOut led2(LED2, "led2"); DigitalOut led3(LED3, "led3"); DigitalOut led4(LED4, "led4"); EthernetNetIf eth; Serial pc(USBTX, USBRX); // Serial USB communications over mbed USB port SDFileSystem sd(p5, p6, p7, p8, "sd"); // mosi, miso, sclk, cs touch_tft tt(p19, p15, p16, p17, p5, p6, p7, p9, p14,"TFT"); // x+,x-,y+,y-,mosi, miso, sclk, cs, reset TextLCD lcdt(p24, /*p25, */p26, p27, p28, p29, p30, TextLCD::LCD16x2); // rs, rw, e, d0, d1, d2, d3 DigitalOut LCDrw(p25, "LCDrw"); // new LCD code no longer requries R/W pin - tie low (J5 on Orange Board) /*--------------------------------------------------------------------------------------------------------------------------------------*/ // Global Variables int gDebug = 1; // display debog level (0 - 3) int OldgDebug = gDebug; // copy of gDebug for updating tft.ini ADC adc(SAMPLE_RATE, 1); bool use_sd = false; // flag for using SDHC file system bool ZeroMinFlag = false; // alignment to 00:00:00 flag float Led1Pwm = 0.01; // LED1 brightness bool Led1Up = true; // LED1 auto up-down float gWait = 0.005; // Main loop wait timeout float const DISP_SLOW(2.0); // Long wait for LCD display float const DISP_FAST(0.5); // Faster wait for LCD char timebuf[32]; // local time format buffer char timebuf_d[32]; // local time format buffer - date only char timebufUTC[32]; // UTC time format buffer int DST = 0; // Daylight Saving Time (or as defined in tft.ini) int OldDST = DST; // Copy of DST for updating tft.ini int TZone = -8; // Time Zone from UTC (or as defined in tft.ini) int OldTZone = TZone; // copy for updating tft.ini time_t ctTime; // get time structure int StartTime; // time we powered up int SysUpTime; // time we've been alive int RTCstep; // value for NTP update interval timer int NTPUpdateValue = 86400; // update RTC every 24 hours (or as defined in tft.ini) int TftCalib = 1; // TFT touchpad calibration, 1=yes (as defined in tft.ini) unsigned int SerialNum[5] = {58,0,0,0,0}; // mbed serial number data int TftDrawColor = 0; // pick pencil color int PenColor = 0xFFFF; // color of pen int PenWidth = 3; // fattness of pen bool PenSizeUp = true; // fatter or skinnier char pOnce = 0; // display the palette only once int CurRot = 0; // object rotation 0-3 int PosX = 120; // object X location int PosY = 160; // object Y location int RTCupdate = 0; // parameter update timer int const RTCUpdateValue = 60; // 600; // update values every minute unsigned int Align1Min=0; // used to align sensor access to exactly every minute, on the minute unsigned int Align10Min=0; // same as above for 10 minute (i.e. 0:00min, 10:00min, 20:00min, etc. int minuteAvg = 0.0; // number of minutes between accesses to storage of data unsigned short pp_txm = 0; // tft touchscreen calibration values unsigned short pp_tym = 0; unsigned short pp_txoff = 0; unsigned short pp_tyoff = 0; float Press0Ft = 102.4; // altimeter - assumed pressure at sea level float Saved0Ft = Press0Ft; // saved for later comparison if changed by HTTP float OldPress0Ft = Press0Ft; // another copy for updating tft.ini /*--------------------------------------------------------------------------------------------------------------------------------------*/ // initialize mbed "ini" configuration file if it doesn't already exist -or- updates the ini file if a change is made in s/w void InitIniFile() { FILE *fp = fopen("/local/tft.ini", "w"); if (fp == NULL) { pc.printf("*** Cannot create tft.ini file!!!\n"); } else { // if(gDebug > 1) pc.printf("*** Updating/Creating tft.ini file...\n"); fprintf(fp, "# mbed configuration file\r\n"); fprintf(fp, "\r\n[NTP Servers]\r\n"); // for (int i=0; i<sntp_num_servers; i++) { // fprintf(f, "%s" CRLF, sntp_server_addresses[i]); // } fprintf(fp, "\r\n[Global]\r\n"); char *hostname = DEFAULTHOSTNAME; fprintf(fp, "xMyName=%s\r\n",hostname); //***MyName is broken*** fprintf(fp, "TftCalib=%d\r\n", TftCalib); // 1= calibration required fprintf(fp, "TftCalTxm=%d\r\n", pp_txm); fprintf(fp, "TftCalTym=%d\r\n", pp_tym); fprintf(fp, "TftCalTxOff=%d\r\n", pp_txoff); fprintf(fp, "TftCalTyOff=%d\r\n", pp_tyoff); // char *RtcColor = RTCCOLOR; // char *JunkText = RTCCOLOR; // fprintf(fp, "TftRtcColor=%s\r\n", RtcColor); fprintf(fp, "Timezone(hrs)=%d\r\n", TZone); fprintf(fp, "DstZone(hrs)=%d\r\n", DST); fprintf(fp, "NTPRefresh(sec)=%d\r\n", NTPUpdateValue); fprintf(fp, "PressureSeaLevel=%f\r\n", Press0Ft); fprintf(fp, "gDebugLevel=%d\r\n", gDebug); fprintf(fp, "\r\n##END\r\n"); fclose(fp); } OldgDebug = gDebug; OldDST = DST; OldTZone = TZone; OldPress0Ft = Press0Ft; } /*--------------------------------------------------------------------------------------------------------------------------------------*/ // Trim whitespace/CRLFs from both ends of a given string // for use with routine below char * str_cleanup(char *in) { char * out = in; // Trim leading spaces and CR/LF while (*out == ' ' || *out == '\t' || *out == '\r' || *out == '\n') out ++; // Trim trailing spaces and CR/LF int len = strlen(out)-1; while (out[len] == ' ' || out[len] == '\t' || out[len] == '\r' || out[len] == '\n') { out[len] = '\0'; len--; } return out; } /*--------------------------------------------------------------------------------------------------------------------------------------*/ // Simple ini file parser for SNTP configuration (Case-sensitive!) // This function is intended to be called only before SNTPClientInit(). // Returns: 0 if OK, errno otherwise enum { SECT_NONE, SECT_SERVERS, SECT_GLOBAL, }; //int _SNTPClrAddresses(); /*--------------------------------------------------------------------------------------------------------------------------------------*/ // This routine reads the "ini" file and sets the appropriate variables int SNTPReadIniFile(const char* filename) { if (gDebug > 1) pc.printf("Before: tz:%d dst:%d ntpupd:%d baroZ:%.1f name:%s\n", TZone, DST, NTPUpdateValue, Press0Ft, hostname); FILE *f; char buf[512]; // bool addresses_cleared = false; bool hname = false; f = fopen(filename, "r"); if (!f) return -1; // errno not used? char *buf1, *buf2; int section=SECT_NONE; int line = 0; while (fgets(buf, sizeof(buf)/sizeof(buf[0]), f)) { line++; buf1 = str_cleanup(buf); if (*buf1 == '#' || *buf1 == '\0') continue; // Comment line or empty line - skip if (*buf1 == '[') { // New section if (0 == strncmp(buf1,"[NTP Servers]", sizeof("[NTP Servers]")-1)) { section=SECT_SERVERS; /* if (!addresses_cleared) { // Clear addresses only once. _SNTPClrAddresses(); addresses_cleared = true; } */ } else if (0 == strncmp(buf1,"[Global]", sizeof("[Global]")-1)) { section=SECT_GLOBAL; } else { section=SECT_NONE; fprintf(stderr, "*** File \"%s\", line %d - section \"%s\" is not understood.\r\n", filename, line, buf1); } } else { // Section values switch (section) { case SECT_SERVERS: /* if (_SNTPAddAddress(buf1)) { fprintf(stderr, "File \"%s\", line %d - cannot add server \"%s\" - exceeded allocated slots.\r\n", filename, line, buf1); } break; */ case SECT_GLOBAL: buf2 = strchr(buf1, '='); if (buf2) { *buf2++ = '\0'; // Now buf1 has variable name, buf2 has value buf2 = str_cleanup(buf2); if (0 == strncmp(buf1, "Timezone(hrs)", sizeof("Timezone(hrs)")-1)) { TZone = strtod(buf2, &buf2); } else if (0 == strncmp(buf1, "NTPRefresh(sec)", sizeof("NTPRefresh(sec)")-1)) { NTPUpdateValue = strtod(buf2, &buf2); } else if (0 == strncmp(buf1, "gDebugLevel", sizeof("gDebugLevel")-1)) { gDebug = strtod(buf2, &buf2); } else if (0 == strncmp(buf1, "TftCalib", sizeof("TftCalib")-1)) { TftCalib = strtod(buf2, &buf2); } else if (0 == strncmp(buf1, "TftCalTxm", sizeof("TftCalTxm")-1)) { pp_txm = strtod(buf2, &buf2); } else if (0 == strncmp(buf1, "TftCalTym", sizeof("TftCalTym")-1)) { pp_tym = strtod(buf2, &buf2); } else if (0 == strncmp(buf1, "TftCalTxOff", sizeof("TftCalTxOff")-1)) { pp_txoff = strtod(buf2, &buf2); } else if (0 == strncmp(buf1, "TftCalTyOff", sizeof("TftCalTyOff")-1)) { pp_tyoff = strtod(buf2, &buf2); // } else if (0 == strncmp(buf1, "TftRtcColor", sizeof("TftRtcColor")-1)) { // JunkText = buf2; //pp_tyoff = strtod(buf2, &buf2); // RtcColor = JunkText; // pc.printf("buf2 >> %s JunkText >> %s RtcColor >> %s\n", buf2, JunkText, RtcColor); } else if (0 == strncmp(buf1, "MyName", sizeof("MyName")-1)) { if (hname == false) { hname = true; hostname = buf2; if (gDebug > 1) pc.printf("buf2:%s hn:%s\n", buf2, hostname); } } else if (0 == strncmp(buf1, "PressureSeaLevel", sizeof("PressureSeaLevel")-1)) { Press0Ft = strtof(buf2, &buf2); //} else if (0 == strncmp(buf1, "RtcUtc", sizeof("RtcUtc")-1)) { // gSntpRtcUtc = (bool)strtol(buf2, &buf2, 10); } else if (0 == strncmp(buf1, "DstZone(hrs)", sizeof("DstZone(hrs)")-1)) { DST = strtod(buf2, &buf2); } else { pc.printf("*** File \"%s\", line %d - unrecognized variable \"%s\" in section [Global]\r\n", filename, line, buf1); } } else { pc.printf("*** File \"%s\", line %d - unrecognized statement in section [Global]: %s\r\n", filename, line, buf1); } break; default: pc.printf("*** File \"%s\", line %d - unrecognized statement / no section: %s\r\n", filename, line, buf1); } } } fclose(f); pc.printf("mbed configuration read from \"%s\", %d lines.\r\n", filename, line); pc.printf("- gDebug display level: %d\n", gDebug); pc.printf("- Time Zone: %d hours\n", TZone); if (DST == 0) { pc.printf("- Standard Time\n"); } else { pc.printf("- Daylight Saving Time\n"); } pc.printf("- NTC update: %d seconds\n", NTPUpdateValue); // pc.printf("- Pressure at Seal Level: %.1f kPa\n", Press0Ft); if (TftCalib == 1) { pc.printf("- TFT touchpad calibration required\n"); } else { pc.printf("- No TFT touchpad calibration needed\n"); } pc.printf("- Touch Cal X Base %d\n", pp_txm); pc.printf("- Touch Cal Y Base %d\n", pp_tym); pc.printf("- Touch Cal X Offset %d\n", pp_txoff); pc.printf("- Touch Cal Y Offset %d\n", pp_tyoff); // pc.printf("- RTC Color %s\n", RtcColor); if (gDebug > 1) pc.printf("After: tz:%d dst:%d ntpupd:%d baroZ:%.1f name:%s\n", TZone, DST, NTPUpdateValue, Press0Ft, hostname); OldgDebug = gDebug; OldDST = DST; OldTZone = TZone; OldPress0Ft = Press0Ft; return 0; } /*--------------------------------------------------------------------------------------------------------------------------------------*/ // This routine attempts to update the RTC via an Ethernet NTP server int SetEthTime() { pc.printf("Getting Time from NTP Server\n- Old Time (UTC): %d %s", ctTime, ctime(&ctTime)); int ntpFlag = 0; if(gDebug) pc.printf("- Trying NTP Server: time-a.nist.gov... "); ntpFlag = ntpdate("time-a.nist.gov", &ctTime); if((gDebug) && (ntpFlag)) pc.printf("failed\n- Trying NTP Server: pool.ntp.org... "); if(ntpFlag) { ntpFlag = 0; ntpFlag = ntpdate("pool.ntp.org", &ctTime); if((gDebug) && (ntpFlag)) pc.printf("failed\n- Trying NTP Server: 10.77.127.1... "); if(ntpFlag) { ntpFlag = 0; ntpFlag = ntpdate("10.77.127.1", &ctTime); if((gDebug) && (ntpFlag)) pc.printf("failed\n"); } } // pc.printf("ntpFlag: %d\n", ntpFlag); /* // // Server selection code from HTTPS_618 // Host server(IpAddr(), 123, "time-a.nist.gov"); if (gDebug > 1) pc.printf("NTP result 1 : %d time-a.nist.gov\n", ntp.setTime(server)); if(ntp.setTime(server) == 4) { server.setName("time-b.nist.gov"); if (gDebug > 1) pc.printf("NTP result 2 : %d time-b.nist.gov\n", ntp.setTime(server)); if(ntp.setTime(server) == 4) { server.setName("pool.ntp.org"); if (gDebug > 1) pc.printf("NTP result 3 : %d pool.ntp.org\n", ntp.setTime(server)); if(ntp.setTime(server) == 4) { server.setName("north-america.pool.ntp.org"); if (gDebug > 1) pc.printf("NTP result 4 : %d north-america.pool.ntp.org\n", ntp.setTime(server)); if(ntp.setTime(server) > 2) { server.setName("10.77.127.1"); if (gDebug > 1) pc.printf("NTP result 5 : %d 10.77.127.1\n", ntp.setTime(server)); if(ntp.setTime(server) > 2) { server.setName("74.218.141.2"); if (gDebug > 1) pc.printf("NTP result 6 : %d 74.218.141.2\n", ntp.setTime(server)); pc.printf(" No NTP Server found!!!\n"); lcdt.locate(15,1); //column(0-15), row(0-1) lcdt.printf("x"); //set no NTP flag on LCD } } } } } */ if(ntpFlag == 0) { pc.printf("ok\nSuccessful Time Update\n"); pc.printf("- Time post NTP (UTC): %d %s", ctTime, ctime(&ctTime)); StartTime = ctTime; set_time(ctTime); ctTime = ctTime + ((TZone+DST)*3600); //timezone and dst offsets pc.printf("- Time post NTP (local): %d %s", ctTime, ctime(&ctTime)); RTCstep = ctTime + NTPUpdateValue; //next NTP update ctTime = ctTime + NTPUpdateValue; //next NTP update pc.printf("- Next Update (local): %d %s", ctTime, ctime(&ctTime)); ctTime = ctTime - NTPUpdateValue; return 0; } else { pc.printf("*** NTP Server not Found!!!\n"); return -1; } } /*--------------------------------------------------------------------------------------------------------------------------------------*/ // This routine is used to align "display events" at exactly RTC 60 second and 10 minute intervals void align_access_time() { ctTime = time(NULL); ctTime = ctTime + ((TZone+DST)*3600); //timezone and dst offsets float getMod = fmod(ctTime, 600.0); // modulus count for exact 10 minute adjustments Align1Min = (ctTime + (600 - int(getMod))); // init 10 minute ticker minuteAvg = 1 + (Align1Min - ctTime) / 60; // how many access minutes before 1st store pc.printf("Align10min ct: %d gM: %3d tsA: %d mA: %d \n", ctTime, int(getMod), Align1Min, minuteAvg); getMod = fmod(ctTime,60.0); Align10Min = (ctTime + (60 - int(getMod))); RTCupdate = Align10Min; //Align1Min; pc.printf("Align1min gM: %3d lts: %d\n", int(getMod), Align10Min); } /*--------------------------------------------------------------------------------------------------------------------------------------*/ // This is the initial splash screen for the TEXT LCD void TextLCDTitle() { lcdt.cls(); //init the LCD lcdt.locate(0,0); //column(0-15), row(0-1) lcdt.printf("TFT Driver %d", revision); //print revision on LCD lcdt.locate(0,1); //column(0-15), row(0-1) lcdt.printf("K Braun"); //print -me- on LCD } /*--------------------------------------------------------------------------------------------------------------------------------------*/ // This is the initial TFT splash screen -and- the follow-on screen if the pen selects the "clear_screen" box void InitTft() { int CurrentColor = PenColor; int CurrentTft = TftDrawColor; tt.foreground(Yellow); // set chars to white tt.cls(); // clear the screen tt.set_font((unsigned char*) Arial12x12); // select the font // tt.set_font((unsigned char*) FONT8x8); // tt.set_font((unsigned char*) Courier10x13); // tt.set_font((unsigned char*) Verdana22x21); // tt.set_font((unsigned char*) Book_Antiqua19x19); // tt.cls(); tt.foreground(Yellow); // set chars to white tt.set_orientation(0); tt.locate(0,0); tt.printf(" TFT Touch Test"); tt.locate(0,1); tt.printf(" K. Braun"); tt.locate(0,2); tt.printf(" Rev: %d", revision); tt.locate(13,1); tt.printf("%d", PenWidth); tt.foreground(White); // set chars to white tt.set_orientation(1); tt.rect(5,5,30,30,Red); tt.fillrect(5,35,30,60,CurrentColor); if(CurrentColor == Black) { tt.rect(5,35,30,60,White); // if black, put on white frame } tt.circle(16,80,10, Blue); // PenColor = 0xFFFF; // color of pen // TftDrawColor = 0; // pick pencil color // The following draws that color palette, but only once after a reset if((gDebug >> 0) && (pOnce == 0)) { pOnce = 1; tt.set_orientation(0); tt.set_font((unsigned char*) Arial24x23); tt.locate(3,3); tt.printf("Palette"); tt.set_font((unsigned char*) Arial12x12); int tX = 17; int tY = 90; int tB = 25; tt.fillrect(tX,tY,tX+tB,tY+tB,White); tX = tX+tB+1; tt.fillrect(tX,tY,tX+tB,tY+tB,Orange); tX = tX+tB+1; tt.fillrect(tX,tY,tX+tB,tY+tB,Yellow); tX = tX+tB+1; tt.fillrect(tX,tY,tX+tB,tY+tB,Magenta); tX = tX+tB+1; tt.fillrect(tX,tY,tX+tB,tY+tB,Red); tX = tX+tB+1; tt.fillrect(tX,tY,tX+tB,tY+tB,Cyan); tX = tX+tB+1; tt.fillrect(tX,tY,tX+tB,tY+tB,Green); tX = tX+tB+1; tt.fillrect(tX,tY,tX+tB,tY+tB,Blue); tY = tY+tB+1; tX = 17; tt.fillrect(tX,tY,tX+tB,tY+tB,LightGrey); tX = tX+tB+1; tt.fillrect(tX,tY,tX+tB,tY+tB,DarkGrey); tX = tX+tB+1; tt.fillrect(tX,tY,tX+tB,tY+tB,Olive); tX = tX+tB+1; tt.fillrect(tX,tY,tX+tB,tY+tB,Purple); tX = tX+tB+1; tt.fillrect(tX,tY,tX+tB,tY+tB,Maroon); tX = tX+tB+1; tt.fillrect(tX,tY,tX+tB,tY+tB,DarkCyan); tX = tX+tB+1; tt.fillrect(tX,tY,tX+tB,tY+tB,DarkGreen); tX = tX+tB+1; tt.fillrect(tX,tY,tX+tB,tY+tB,Navy); tt.set_orientation(1); } PenColor = CurrentColor; TftDrawColor = CurrentTft; //wait for no-touch point p; do { p = tt.get_touch(); tt.is_touched(p); } while (p.y > 0x2000 | p.x > 0x2000); // { // wait for no touch } /*--------------------------------------------------------------------------------------------------------------------------------------*/ // The following draws an object of a triode tube. It's location is set by PosX and PosY and CurRot void DrawTubeX() { int xx = PosX; int yy = PosY; if((CurRot == 0) || (CurRot == 2)) { xx = PosX; yy = PosY; } else { xx = PosY; yy = PosX; } tt.set_orientation(CurRot); tt.fillcircle(xx,yy,60,Orange); tt.circle(xx,yy,60,Navy); tt.circle(xx,yy,59,Blue); tt.circle(xx,yy,58,Navy); tt.fillrect(xx-2,yy+40,xx+2,yy+70,Purple); tt.fillrect(xx-2,yy+10,xx+2,yy+30,Purple); tt.fillrect(xx-2,yy-20,xx+2,yy+00,Purple); tt.fillrect(xx-2,yy-50,xx+2,yy-30,Purple); tt.fillrect(xx-80,yy-2,xx-30,yy+2,DarkGreen); tt.fillrect(xx-30,yy-30,xx-25,yy+30,DarkGreen); tt.fillrect(xx+25,yy-30,xx+30,yy+30,Maroon); tt.fillrect(xx+25,yy-30,xx+40,yy-25,Maroon); tt.fillrect(xx+25,yy+25,xx+75,yy+30,Maroon); } /*--------------------------------------------------------------------------------------------------------------------------------------*/ // The following draws the tube object in all for rotations, based on CurRot void DrawTube() { CurRot = 2; DrawTubeX(); wait(DISP_SLOW); wait(DISP_SLOW); for(CurRot = 0 ; CurRot < 4 ; CurRot++) { tt.cls(); DrawTubeX(); wait(DISP_FAST); // wait(DISP_SLOW); } } /*--------------------------------------------------------------------------------------------------------------------------------------*/ // Routine used to change the pen's color palette on the TFT void TftNewColor() { // point p; TftDrawColor++; if(TftDrawColor >= 17) { TftDrawColor = 0; } switch (TftDrawColor) { case 0: { tt.fillrect(5,35,30,60,White); PenColor = White; } break; case 1: { tt.fillrect(5,35,30,60,Orange); PenColor = Orange; } break; case 2: { tt.fillrect(5,35,30,60,Yellow); PenColor = Yellow; } break; case 3: { tt.fillrect(5,35,30,60,Magenta); PenColor = 0xF81F; } break; case 4: { tt.fillrect(5,35,30,60,Red); PenColor = 0xF800; } break; case 5: { tt.fillrect(5,35,30,60,Cyan); PenColor = 0x07FF; } break; case 6: { tt.fillrect(5,35,30,60,Green); PenColor = 0x07E0; } break; case 7: { tt.fillrect(5,35,30,60,Blue); PenColor = 0x001F; } break; case 8: { tt.fillrect(5,35,30,60,LightGrey); PenColor = 0x7BEF; } break; case 9: { tt.fillrect(5,35,30,60,DarkGrey); PenColor = 0xC618; } break; case 10: { tt.fillrect(5,35,30,60,Olive); PenColor = 0x7BE0; } break; case 11: { tt.fillrect(5,35,30,60,Purple); PenColor = 0x780F; } break; case 12: { tt.fillrect(5,35,30,60,Maroon); PenColor = 0x7800; } break; case 13: { tt.fillrect(5,35,30,60,DarkCyan); PenColor = 0x03EF; } break; case 14: { tt.fillrect(5,35,30,60,DarkGreen); PenColor = 0x03E0; } break; case 15: { tt.fillrect(5,35,30,60,Navy); PenColor = 0x000F; } break; case 16: { tt.fillrect(5,35,30,60,Black); tt.rect(5,35,30,60,White); PenColor = 0x0000; } break; } // end of switch //wait for no-touch point p; do { p = tt.get_touch(); tt.is_touched(p); // pc.printf("pr1: %d %d\n", p.x, p.y); } while (p.y > 0x2000 | p.x > 0x2000); // { // wait for no touch } /*--------------------------------------------------------------------------------------------------------------------------------------*/ // Find the "secret spot" on the TFT, RESET the mbed void KillMbed() { // text LCD lcdt.cls(); // clear out text LCD lcdt.locate(0,0); // column(0-15), row(0-1) lcdt.printf("Pen select\n"); lcdt.printf("resetting mbed!!"); // CRT pc.printf("### Pen detected reset area. Resetting mbed!!!! ###\n"); //wait for no-touch point p; do { p = tt.get_touch(); tt.is_touched(p); } while (p.y > 0x2000 | p.x > 0x2000); // { // wait for no touch // TFT LCD tt.cls(); tt.foreground(Yellow); tt.set_orientation(1); tt.set_font((unsigned char*) Book_Antiqua19x19); tt.locate(2,5); // x,y tt.printf("### Reset mbed ###"); wait(DISP_SLOW); wait(DISP_SLOW); mbed_reset(); } /*--------------------------------------------------------------------------------------------------------------------------------------*/ // This routing changes the "width" or "fatness" of the drawing pen on the TFT void TftNewPenSize() { PenWidth++; if(PenWidth > 8) { PenWidth = 1; } tt.foreground(Yellow); // set chars to white tt.set_orientation(0); tt.locate(13,1); tt.printf("%d", PenWidth); tt.set_orientation(1); tt.circle(16,80,10, Blue); tt.foreground(PenColor); //wait for no-touch point p; do { p = tt.get_touch(); tt.is_touched(p); // pc.printf("pr1: %d %d\n", p.x, p.y); } while (p.y > 0x2000 | p.x > 0x2000); // { // wait for no touch } /*--------------------------------------------------------------------------------------------------------------------------------------*/ //A generic QUICK BROWN FOX routine to check out various fonts void QuickBrownFox() { tt.foreground(Yellow); // set chars to white tt.cls(); // clear the screen // tt.set_font((unsigned char*) Arial12x12); // select the font // tt.set_font((unsigned char*) Courier10x13); // select the font // tt.set_font((unsigned char*) Verdana22x21); // select the font // tt.set_font((unsigned char*) Book_Antiqua19x19); // select the font tt.set_orientation(1); tt.locate(0,0); tt.printf("THE QUICK BROWN FOX"); tt.locate(0,1); tt.printf("JUMPED OVER THE LAZY"); tt.locate(0,2); tt.printf("DOG'S BACK 0123456789"); tt.locate(0,3); tt.printf("!@#$%^&*(){|}[\]:;<,./?>"); tt.locate(0,5); tt.printf("the quick brown fox"); tt.locate(0,6); tt.printf("jumped over the lazy "); tt.locate(0,7); tt.printf("dog's back \n"); tt.foreground(White); // set chars to white tt.set_orientation(1); } /*--------------------------------------------------------------------------------------------------------------------------------------*/ int main() { pc.baud(921600); //set up USB serial speed // time_t ctTime; ctTime = time(NULL); StartTime = ctTime; //get time we started up ctTime = ctTime + ((TZone+DST)*3600); //timezone and dst offsets RTCstep = ctTime; pc.printf("\n\n"); pc.printf("-------------------------------------------------------------------\n"); pc.printf("TFT and Touch Screen Test Routines Rev: %d K Braun\n", revision); TextLCDTitle(); pc.printf("Graphic elements/text displayed\n"); // point p; // tt.claim(stdout); // send stdout to the TFT display tt.background(Black); // set background to black tt.foreground(Yellow); // set chars to white tt.cls(); // clear the screen tt.set_font((unsigned char*) Arial12x12); // select the font tt.set_orientation(0); tt.locate(0,0); tt.printf(" Revision: %d", revision); tt.foreground(White); // set chars to white tt.set_orientation(1); tt.set_font((unsigned char*) Arial24x23); tt.locate(3,9); // x,y tt.printf("Graphic Test"); // some graphics tt.line(0,0,100,200,Green); tt.rect(20,40,70,90,Red); tt.fillrect(240,25,260,70,Blue); tt.fillrect(265,25,285,70,Blue); tt.circle(30,180,10,Purple); tt.circle(55,175,10,DarkGreen); tt.circle(40,155,10,DarkCyan); DrawTube(); CurRot = 1; tt.cls(); DrawTubeX(); PosX = 40; PosY = 50; DrawTubeX(); PosX = 190; PosY = 50; DrawTubeX(); PosX = 40; PosY = 280; DrawTubeX(); PosX = 190; PosY = 280; DrawTubeX(); wait(DISP_SLOW); wait(DISP_SLOW); // Check if we can use modify the http name of the mbed FILE *fp = fopen("/local/whoami.ini", "r"); if (fp == NULL) { pc.printf("*** No /local/whoami.ini file, defaulting to: %s\n",hostname); } else { char localbuf[64]; hostname = fgets(localbuf, sizeof(localbuf)-1, fp); pc.printf("Found /local/whoami.ini file. my name is: %s\n",hostname); fclose(fp); } // Check for main ini file, create if does not exist FILE *fpi = fopen("/local/tft.ini", "r"); if (fpi == NULL) { InitIniFile(); pc.printf("*** rebooting after file creation...."); wait(2.0); mbed_reset(); } else { pc.printf("Found /local/tft.ini file...\n"); fclose(fpi); SNTPReadIniFile("/local/tft.ini"); } /*See if INDEX.HTM can be created on SD micro drive */ // //NOTE: mbed hangs if no SD card installed - need to fix!!!!!! // lcdt.cls(); //init the LCD lcdt.locate(0,0); //column(0-15), row(0-1) lcdt.printf("SD Card Missing!"); //---in case SD drive hangs forever--- if (gDebug > 3) { // char *WriteTest = "This is a Test!!!"; fp = fopen("/sd/INDEX.HTM", "w+"); if (fp == NULL) { pc.printf("*** Cannot create INDEX.HTM file\n"); } else { // char localbuf[32]; // localbuf = WriteTest; fprintf(fp, "This is a Test!!!\n"); pc.printf("Creating /sd/INDEX.HTM file\n"); fclose(fp); } } fp = fopen("/sd/index.htm", "r"); if (fp == NULL) { use_sd = false; if (gDebug) pc.printf("*** Found SD card, -no- INDEX.HTM file\n"); } else { use_sd = true; fclose(fp); if (gDebug) pc.printf("Found SD card with INDEX.HTM file\n"); } lcdt.cls(); // if (0 != SNTPReadIniFile("/sd/sntp.ini") ) // SNTPReadIniFile("/local/sntp.ini"); // SNTPWriteIniFile(stdout); // fclose(fpi); // lcdt.cls(); //init the LCD if ((use_sd == true) && (gDebug > 3)) pc.printf(" "); // to get rid of use_sd "never used" warning //Check RTC ctTime = time(NULL); ctTime = ctTime + ((TZone+DST)*3600); //timezone and dst offsets if (RTCstep == ctTime) { pc.printf("*** RTC stopped, initializing the RTC. !!CHECK BATTERY!!\n"); pc.printf("*** Note: Time is incorrect, needs to be updated!!!\n"); set_time(1296473737); lcdt.cls(); //init the LCD lcdt.locate(0,0); //column(0-15), row(0-1) lcdt.printf("RTC Stopped!!"); wait(DISP_SLOW); // strftime(timebuf, 32, "%H:%M\n", localtime(&ctTime)); } else { lcdt.cls(); //init the LCD lcdt.locate(0,0); //column(0-15), row(0-1) lcdt.printf("RTC running"); pc.printf("RTC running\n"); } tt.cls(); if(TftCalib == 1) { lcdt.locate(0,1); //column(0-15), row(0-1) lcdt.printf("Cal t-pad..."); pc.printf("Calibrating touchpad....."); tt.calibrate(); // calibrate the touch pc.printf(" Updating /local/tft.ini file....."); TftCalib = 0; //set -no cal reqd- flag pp_txm = tt.getCalDataX(); //get calibration values pp_tym = tt.getCalDataY(); pp_txoff = tt.getCalOffX(); pp_tyoff = tt.getCalOffY(); InitIniFile(); //save in ini file pc.printf(" done\n"); pc.printf("New Touch Cal Values:\n- Touch Cal X Base %d\n- Touch Cal Y Base %d\n- Touch Cal X Offset %d\n- Touch Cal Y Offset %d\n" , pp_txm, pp_tym, pp_txoff, pp_tyoff); lcdt.cls(); } else { pc.printf("No touchpad cal needed\n"); tt.setCalDataX(pp_txm); //set calibration values tt.setCalDataY(pp_tym); tt.setCalOffX(pp_txoff); tt.setCalOffY(pp_tyoff); } TextLCDTitle(); tt.cls(); tt.foreground(Yellow); // set chars to white // tt.cls(); // clear the screen // tt.set_font((unsigned char*) Arial12x12); // select the font tt.set_font((unsigned char*) Courier10x13); // select the font // tt.set_font((unsigned char*) Verdana22x21); // select the font // tt.set_font((unsigned char*) Book_Antiqua19x19); // select the font pc.printf("Quick Brown Fox displayed\n"); QuickBrownFox(); // wait(DISP_SLOW); // wait(DISP_SLOW); // pc.printf("(before) ctTime %d\n", ctTime); //Set up Ethernet EthernetErr ethErr; pc.printf("Starting Ethernet...\n"); ethErr = eth.setup(); if(ethErr) { pc.printf("*** No Ethernet Link!!!\n"); } else { IpAddr ethIp = eth.getIp(); pc.printf("IP address : %d.%d.%d.%d\n", ethIp[0], ethIp[1], ethIp[2], ethIp[3]); lcdt.cls(); lcdt.printf("%d.%d.%d.%d\n", ethIp[0], ethIp[1], ethIp[2], ethIp[3]); lcdt.locate(0,1); //column(0-15), row(0-1) lcdt.printf("tft%d", revision); SetEthTime(); } InitTft(); point p; int LedDelay = 0; int xTime = ctTime; // pc.printf("RtcColor %s\n", RtcColor); pc.printf("Ready...\n"); // pc.printf("(after) ctTime %d\ xTime %d\n", ctTime, xTime); while (1) { ctTime = time(NULL); SysUpTime = ctTime - StartTime; //number of seconds we've been alive // if(gDebug > 1) pc.printf("cT: %d sT: %d suT: %d\n", ctTime, StartTime, SysUpTime); ctTime = ctTime + ((TZone + DST) * 3600); //timezone and dst offsets strftime(timebuf, 32, "%H:%M:%S", localtime(&ctTime)); if(xTime != ctTime) { xTime = ctTime; if(gDebug > 1) pc.printf("cT: %d sT: %d suT: %d\n", ctTime, StartTime, SysUpTime); lcdt.locate(8,1); //column(0-15), row(0-1) lcdt.printf("%s\n", timebuf); lcdt.locate(15,1); tt.foreground (Cyan); tt.set_orientation(0); tt.locate(14,25); //25 tt.printf("%s", timebuf ); strftime(timebuf, 32, "%m/%d/%y", localtime(&ctTime)); tt.locate(14,24); //24 tt.printf("%s", timebuf ); } // Winking LED1 LedDelay++; if(LedDelay >= 24) { LedDelay = 0; if(Led1Up == true) { Led1Pwm = Led1Pwm + 0.005; led1 = Led1Pwm; if(Led1Pwm >= 0.20) { Led1Up = false; } } else { Led1Pwm = Led1Pwm - 0.005; led1 = Led1Pwm; if(Led1Pwm <= 0.005) { Led1Up = true; } } } tt.set_orientation(1); p = tt.get_touch(); // read analog pos. if (tt.is_touched(p)) { // test if touched // pc.printf("p1: %d %d\n", p.x, p.y); // inside the red box tt.rect(5,5,30,30,Red); if((p.x >= 10000) && (p.x <= 15500) && (p.y >= 10500) && (p.y <= 16300)) { // clear out TFT LCD red box InitTft(); } else if((p.x >= 10000) && (p.x <= 15500) && (p.y >= 16400) && (p.y <= 21300)) { // pen color select colored box TftNewColor(); } else if((p.x >= 10000) && (p.x <= 15500) && (p.y >= 21400) && (p.y <= 29000)) { // pen width select blue circle TftNewPenSize(); } else if((p.x >= 10000) && (p.x <= 12000) && (p.y >= 50000) && (p.y <= 55000)) { // hidden system-reboot near "TFT" text KillMbed(); } else { p = tt.to_pixel(p); // convert to pixel pos tt.fillcircle(p.x,p.y,PenWidth,PenColor); // print a blue dot on the screen } // pc.printf("p2: %d\n", p); } } }