Driving a 20T202DA2JA VFD, using the (powered) RTC, pressing a button to ask the user to enter the date details over serial, displaying the date on the VFD. Now with added ethernet and NTP to update the time automatically on startup.
Dependencies: EthernetNetIf mbed DNSResolver NTPClientMin
main.cpp@1:abc0162903bf, 2010-11-24 (annotated)
- Committer:
- u0421793
- Date:
- Wed Nov 24 22:12:52 2010 +0000
- Revision:
- 1:abc0162903bf
- Parent:
- 0:3ba54e2bf65d
- Child:
- 2:f33d74cebc4c
changed the logic for ascertaining the date suffix, now assume the RTC is battery backed, added a button (active low, pullup) to ask the time setting over serial.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
u0421793 | 0:3ba54e2bf65d | 1 | #include "mbed.h" |
u0421793 | 0:3ba54e2bf65d | 2 | |
u0421793 | 0:3ba54e2bf65d | 3 | // rudimentary driving of a 20T202DA2JA vacuum fluorescent display, 20 chars x 2 lines |
u0421793 | 0:3ba54e2bf65d | 4 | // display has 5 pins |
u0421793 | 0:3ba54e2bf65d | 5 | // 1 - green - GND |
u0421793 | 0:3ba54e2bf65d | 6 | // 2 - yellow - Vcc |
u0421793 | 0:3ba54e2bf65d | 7 | // 3 - orange - SIO - serial data - MOSI - p5 |
u0421793 | 0:3ba54e2bf65d | 8 | // 4 - red - /STB - active low device select - p8 |
u0421793 | 0:3ba54e2bf65d | 9 | // 5 - brown - SCK - serial clock - sclk - p7 |
u0421793 | 0:3ba54e2bf65d | 10 | |
u0421793 | 1:abc0162903bf | 11 | // Also, I have fitted a battery on my breadboard to the RTC, to keep the time across power downs. |
u0421793 | 1:abc0162903bf | 12 | |
u0421793 | 0:3ba54e2bf65d | 13 | // VFD |
u0421793 | 0:3ba54e2bf65d | 14 | SPI spi(p5, p6, p7); // mosi, miso, sclk (miso not used by display) |
u0421793 | 0:3ba54e2bf65d | 15 | DigitalOut cs(p8); // chip select (active low) |
u0421793 | 0:3ba54e2bf65d | 16 | |
u0421793 | 1:abc0162903bf | 17 | // button (push) |
u0421793 | 1:abc0162903bf | 18 | DigitalIn set_the_time_button (p30); // “set the time” button (active low, pullup resistor) |
u0421793 | 1:abc0162903bf | 19 | |
u0421793 | 0:3ba54e2bf65d | 20 | void DATA(unsigned char displaying) { |
u0421793 | 0:3ba54e2bf65d | 21 | // Select the device by setting chip select low |
u0421793 | 0:3ba54e2bf65d | 22 | cs = 0; |
u0421793 | 0:3ba54e2bf65d | 23 | spi.write(0xfa); |
u0421793 | 0:3ba54e2bf65d | 24 | spi.write(displaying); |
u0421793 | 0:3ba54e2bf65d | 25 | // Deselect the device |
u0421793 | 0:3ba54e2bf65d | 26 | cs = 1; |
u0421793 | 0:3ba54e2bf65d | 27 | } |
u0421793 | 0:3ba54e2bf65d | 28 | |
u0421793 | 0:3ba54e2bf65d | 29 | void COM(unsigned char telling) { |
u0421793 | 0:3ba54e2bf65d | 30 | // Select the device by setting chip select low |
u0421793 | 0:3ba54e2bf65d | 31 | cs = 0; |
u0421793 | 0:3ba54e2bf65d | 32 | spi.write(0xf8); |
u0421793 | 0:3ba54e2bf65d | 33 | spi.write(telling); |
u0421793 | 0:3ba54e2bf65d | 34 | // Deselect the device |
u0421793 | 0:3ba54e2bf65d | 35 | cs = 1; |
u0421793 | 0:3ba54e2bf65d | 36 | } |
u0421793 | 0:3ba54e2bf65d | 37 | |
u0421793 | 0:3ba54e2bf65d | 38 | void INITIALISE_DISPLAY() { |
u0421793 | 0:3ba54e2bf65d | 39 | COM(0x01); //clear all display and set DD-RAM address 0 in address counter |
u0421793 | 0:3ba54e2bf65d | 40 | COM(0x02); //move cursor to the original position |
u0421793 | 0:3ba54e2bf65d | 41 | COM(0x06); //set the cursor direction increment and cursor shift enabled |
u0421793 | 0:3ba54e2bf65d | 42 | COM(0x38); //set 8bit operation,2 line display and 100% brightness level |
u0421793 | 0:3ba54e2bf65d | 43 | COM(0x80); //set cursor to the first position of 1st line |
u0421793 | 0:3ba54e2bf65d | 44 | COM(0x0c); //set display on,cursor on,blinking off |
u0421793 | 0:3ba54e2bf65d | 45 | } |
u0421793 | 0:3ba54e2bf65d | 46 | |
u0421793 | 1:abc0162903bf | 47 | tm ASK_FOR_THE_TIME(struct tm t) { |
u0421793 | 0:3ba54e2bf65d | 48 | // get the current time from the terminal by asking the user to enter |
u0421793 | 0:3ba54e2bf65d | 49 | // unfortunately, there's no echo back, so they can't see what they type |
u0421793 | 1:abc0162903bf | 50 | |
u0421793 | 0:3ba54e2bf65d | 51 | //year |
u0421793 | 0:3ba54e2bf65d | 52 | printf("Enter year:\n"); // ask to enter year |
u0421793 | 0:3ba54e2bf65d | 53 | printf("YYYY[enter]\n"); // as YYYY |
u0421793 | 0:3ba54e2bf65d | 54 | scanf("%d", &t.tm_year); // put the typing into here |
u0421793 | 0:3ba54e2bf65d | 55 | |
u0421793 | 0:3ba54e2bf65d | 56 | //month |
u0421793 | 0:3ba54e2bf65d | 57 | printf("Enter month:\n"); // ask to enter month |
u0421793 | 0:3ba54e2bf65d | 58 | printf("MM[enter]\n"); // as MM |
u0421793 | 0:3ba54e2bf65d | 59 | scanf("%d", &t.tm_mon); // put the typing into here |
u0421793 | 0:3ba54e2bf65d | 60 | |
u0421793 | 0:3ba54e2bf65d | 61 | //date |
u0421793 | 0:3ba54e2bf65d | 62 | printf("Enter date:\n"); // ask to enter date |
u0421793 | 0:3ba54e2bf65d | 63 | printf("DD[enter]\n"); // as DD |
u0421793 | 0:3ba54e2bf65d | 64 | scanf("%d", &t.tm_mday); // put the typing into here |
u0421793 | 0:3ba54e2bf65d | 65 | |
u0421793 | 0:3ba54e2bf65d | 66 | //hours |
u0421793 | 0:3ba54e2bf65d | 67 | printf("Enter hours:\n"); // ask to enter hours |
u0421793 | 0:3ba54e2bf65d | 68 | printf("HH[enter]\n"); // as HH |
u0421793 | 0:3ba54e2bf65d | 69 | scanf("%d", &t.tm_hour); // put the typing into here |
u0421793 | 0:3ba54e2bf65d | 70 | |
u0421793 | 0:3ba54e2bf65d | 71 | //minutes |
u0421793 | 0:3ba54e2bf65d | 72 | printf("Enter minutes:\n"); // ask to enter minutes |
u0421793 | 0:3ba54e2bf65d | 73 | printf("MM[enter]\n"); // as MM |
u0421793 | 0:3ba54e2bf65d | 74 | scanf("%d", &t.tm_min); // put the typing into here |
u0421793 | 0:3ba54e2bf65d | 75 | |
u0421793 | 0:3ba54e2bf65d | 76 | //seconds |
u0421793 | 0:3ba54e2bf65d | 77 | printf("Enter seconds:\n"); // ask to enter seconds |
u0421793 | 0:3ba54e2bf65d | 78 | printf("SS[enter]\n"); // as SS |
u0421793 | 0:3ba54e2bf65d | 79 | scanf("%d", &t.tm_sec); // put the typing into here |
u0421793 | 0:3ba54e2bf65d | 80 | |
u0421793 | 0:3ba54e2bf65d | 81 | // adjust for tm structure required values |
u0421793 | 0:3ba54e2bf65d | 82 | t.tm_year = t.tm_year - 1900; |
u0421793 | 0:3ba54e2bf65d | 83 | t.tm_mon = t.tm_mon - 1; |
u0421793 | 0:3ba54e2bf65d | 84 | |
u0421793 | 0:3ba54e2bf65d | 85 | // set the time |
u0421793 | 0:3ba54e2bf65d | 86 | set_time(mktime(&t)); |
u0421793 | 0:3ba54e2bf65d | 87 | //set_time(1289676600); // Set RTC time to Sat, 13 Nov 2010 19:30:00 in case of testing |
u0421793 | 0:3ba54e2bf65d | 88 | |
u0421793 | 1:abc0162903bf | 89 | return t; |
u0421793 | 1:abc0162903bf | 90 | |
u0421793 | 1:abc0162903bf | 91 | } |
u0421793 | 1:abc0162903bf | 92 | // spare display testing string |
u0421793 | 1:abc0162903bf | 93 | // char theString[41] = {"20T202DA2JA VFD driven by mbed using SPI"}; // forty characters max |
u0421793 | 1:abc0162903bf | 94 | char timeStringTop[21], timeStringBottom1[3], timeStringBottom2[17]; // string to put the time representation into |
u0421793 | 1:abc0162903bf | 95 | |
u0421793 | 1:abc0162903bf | 96 | char day_suffix[3] = "th"; // suffix string for days like 1st 2nd 3rd |
u0421793 | 1:abc0162903bf | 97 | char first[3]= "st", second[3] = "nd", third[3] = "rd"; // holding strings for the suffixes |
u0421793 | 1:abc0162903bf | 98 | |
u0421793 | 1:abc0162903bf | 99 | int main() { |
u0421793 | 1:abc0162903bf | 100 | // Setup the spi for 8 bit data, high steady state clock, |
u0421793 | 1:abc0162903bf | 101 | // second edge capture, with a 1MHz clock rate |
u0421793 | 1:abc0162903bf | 102 | spi.format(8,3); // set SPI mode |
u0421793 | 1:abc0162903bf | 103 | spi.frequency(1000000); |
u0421793 | 1:abc0162903bf | 104 | |
u0421793 | 1:abc0162903bf | 105 | INITIALISE_DISPLAY(); // call the function that initialises the VFD |
u0421793 | 1:abc0162903bf | 106 | |
u0421793 | 0:3ba54e2bf65d | 107 | while (1) { |
u0421793 | 1:abc0162903bf | 108 | struct tm t; |
u0421793 | 1:abc0162903bf | 109 | |
u0421793 | 1:abc0162903bf | 110 | if (set_the_time_button == false) { |
u0421793 | 1:abc0162903bf | 111 | ASK_FOR_THE_TIME(t); |
u0421793 | 1:abc0162903bf | 112 | } |
u0421793 | 0:3ba54e2bf65d | 113 | |
u0421793 | 0:3ba54e2bf65d | 114 | time_t rtc_seconds = time(NULL); // somehow gets the current amount of seconds, evah! |
u0421793 | 0:3ba54e2bf65d | 115 | |
u0421793 | 1:abc0162903bf | 116 | int i = 0; // initalise the character steppers |
u0421793 | 1:abc0162903bf | 117 | |
u0421793 | 1:abc0162903bf | 118 | // build the two lines of the display separately |
u0421793 | 1:abc0162903bf | 119 | strftime(timeStringTop, 20, "%X %A %p ", localtime(&rtc_seconds)); // put the hours:minutes:seconds, then full day, then am/pm |
u0421793 | 1:abc0162903bf | 120 | |
u0421793 | 1:abc0162903bf | 121 | COM(0x80); // first line |
u0421793 | 1:abc0162903bf | 122 | for (i=0; i<20; i++) { |
u0421793 | 1:abc0162903bf | 123 | DATA(timeStringTop[i]); // step through the top line |
u0421793 | 1:abc0162903bf | 124 | } |
u0421793 | 1:abc0162903bf | 125 | |
u0421793 | 1:abc0162903bf | 126 | // this builds the second line in three pieces |
u0421793 | 1:abc0162903bf | 127 | strftime(timeStringBottom1, 2, "%e", localtime(&rtc_seconds)); // put the date in |
u0421793 | 1:abc0162903bf | 128 | strftime(timeStringBottom2, 16, " %B %Y ", localtime(&rtc_seconds)); // put a space then the full month then the year then spaces |
u0421793 | 1:abc0162903bf | 129 | |
u0421793 | 0:3ba54e2bf65d | 130 | // first do a quick check to see if our date needs a 'st'; 'nd'; 'rd' or 'th' suffix |
u0421793 | 1:abc0162903bf | 131 | if ((t.tm_mday < 10) | (t.tm_mday > 20)) { // if the date is below the 10th or above the 20th |
u0421793 | 0:3ba54e2bf65d | 132 | switch (t.tm_mday%10) { |
u0421793 | 0:3ba54e2bf65d | 133 | case 1: |
u0421793 | 0:3ba54e2bf65d | 134 | strcpy (day_suffix,first); // is it a day that needs a "st"? |
u0421793 | 0:3ba54e2bf65d | 135 | break; |
u0421793 | 0:3ba54e2bf65d | 136 | case 2: |
u0421793 | 0:3ba54e2bf65d | 137 | strcpy (day_suffix,second); // is it a day that needs a "nd" |
u0421793 | 0:3ba54e2bf65d | 138 | break; |
u0421793 | 0:3ba54e2bf65d | 139 | case 3: |
u0421793 | 0:3ba54e2bf65d | 140 | strcpy (day_suffix,third); // is it a day that needs a "rd" |
u0421793 | 0:3ba54e2bf65d | 141 | break; |
u0421793 | 0:3ba54e2bf65d | 142 | default: |
u0421793 | 0:3ba54e2bf65d | 143 | break; // leave 'day_suffix' saying "th" then. |
u0421793 | 0:3ba54e2bf65d | 144 | } |
u0421793 | 0:3ba54e2bf65d | 145 | } |
u0421793 | 0:3ba54e2bf65d | 146 | |
u0421793 | 0:3ba54e2bf65d | 147 | COM(0xc0); // second line |
u0421793 | 0:3ba54e2bf65d | 148 | for (i=0; i<2; i++) { |
u0421793 | 0:3ba54e2bf65d | 149 | DATA(timeStringBottom1[i]); // step through the first part of the bottom line |
u0421793 | 0:3ba54e2bf65d | 150 | } |
u0421793 | 0:3ba54e2bf65d | 151 | for (i=0; i<2; i++) { |
u0421793 | 0:3ba54e2bf65d | 152 | DATA(day_suffix[i]); // then add the day suffix |
u0421793 | 0:3ba54e2bf65d | 153 | } |
u0421793 | 0:3ba54e2bf65d | 154 | for (i=0; i<17; i++) { |
u0421793 | 0:3ba54e2bf65d | 155 | DATA(timeStringBottom2[i]); // finish stepping through the bottom line |
u0421793 | 0:3ba54e2bf65d | 156 | } |
u0421793 | 0:3ba54e2bf65d | 157 | |
u0421793 | 0:3ba54e2bf65d | 158 | wait(1); |
u0421793 | 0:3ba54e2bf65d | 159 | } |
u0421793 | 0:3ba54e2bf65d | 160 | |
u0421793 | 0:3ba54e2bf65d | 161 | } |