program to interface bbc microbit to a MCP79410 RTCC module
Fork of microbit-hello-world by
This program uses the BBC microbit to display a clock. The program scrolls the time across the microbit 25 led display. The user can set the hours with button A and minutes with button B. The seconds can also be displayed but cannot be set on this version of the program.
main.cpp@2:92208e3aae5a, 2018-01-11 (annotated)
- Committer:
- euxton
- Date:
- Thu Jan 11 21:55:57 2018 +0000
- Revision:
- 2:92208e3aae5a
- Parent:
- 1:75322449b2fd
1st commit;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
LancasterUniversity | 0:0041f35b0c4c | 1 | /* |
LancasterUniversity | 0:0041f35b0c4c | 2 | The MIT License (MIT) |
LancasterUniversity | 0:0041f35b0c4c | 3 | |
LancasterUniversity | 0:0041f35b0c4c | 4 | Copyright (c) 2016 British Broadcasting Corporation. |
LancasterUniversity | 0:0041f35b0c4c | 5 | This software is provided by Lancaster University by arrangement with the BBC. |
LancasterUniversity | 0:0041f35b0c4c | 6 | |
LancasterUniversity | 0:0041f35b0c4c | 7 | Permission is hereby granted, free of charge, to any person obtaining a |
LancasterUniversity | 0:0041f35b0c4c | 8 | copy of this software and associated documentation files (the "Software"), |
LancasterUniversity | 0:0041f35b0c4c | 9 | to deal in the Software without restriction, including without limitation |
LancasterUniversity | 0:0041f35b0c4c | 10 | the rights to use, copy, modify, merge, publish, distribute, sublicense, |
LancasterUniversity | 0:0041f35b0c4c | 11 | and/or sell copies of the Software, and to permit persons to whom the |
LancasterUniversity | 0:0041f35b0c4c | 12 | Software is furnished to do so, subject to the following conditions: |
LancasterUniversity | 0:0041f35b0c4c | 13 | |
LancasterUniversity | 0:0041f35b0c4c | 14 | The above copyright notice and this permission notice shall be included in |
LancasterUniversity | 0:0041f35b0c4c | 15 | all copies or substantial portions of the Software. |
LancasterUniversity | 0:0041f35b0c4c | 16 | |
LancasterUniversity | 0:0041f35b0c4c | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
LancasterUniversity | 0:0041f35b0c4c | 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
LancasterUniversity | 0:0041f35b0c4c | 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
LancasterUniversity | 0:0041f35b0c4c | 20 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
LancasterUniversity | 0:0041f35b0c4c | 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
LancasterUniversity | 0:0041f35b0c4c | 22 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
LancasterUniversity | 0:0041f35b0c4c | 23 | DEALINGS IN THE SOFTWARE. |
LancasterUniversity | 0:0041f35b0c4c | 24 | */ |
euxton | 1:75322449b2fd | 25 | /* This Microbit program for RTCC MCP7941X demonstrates use of: |
euxton | 1:75322449b2fd | 26 | the I2C interface, |
euxton | 1:75322449b2fd | 27 | button events to set the clock, |
euxton | 1:75322449b2fd | 28 | scrolling to display the time, |
euxton | 1:75322449b2fd | 29 | author phil.holifield@gmail.com |
euxton | 1:75322449b2fd | 30 | any comments welcome |
euxton | 1:75322449b2fd | 31 | */ |
LancasterUniversity | 0:0041f35b0c4c | 32 | |
LancasterUniversity | 0:0041f35b0c4c | 33 | #include "MicroBit.h" |
LancasterUniversity | 0:0041f35b0c4c | 34 | |
LancasterUniversity | 0:0041f35b0c4c | 35 | MicroBit uBit; |
LancasterUniversity | 0:0041f35b0c4c | 36 | |
euxton | 1:75322449b2fd | 37 | // for MCP7941X I2C control byte – 0xDE for RTCC |
euxton | 1:75322449b2fd | 38 | const int addr = 0xDE; // 8 bit addressing |
euxton | 1:75322449b2fd | 39 | char config_t[10]; |
euxton | 1:75322449b2fd | 40 | char tim_read[8]; |
euxton | 1:75322449b2fd | 41 | char disp_time[8]; |
euxton | 1:75322449b2fd | 42 | char MSN, LSN, ch_hrs, ch_mins; |
euxton | 1:75322449b2fd | 43 | int secs, mins, hrs; |
euxton | 1:75322449b2fd | 44 | int inc_hr, inc_mins; |
euxton | 1:75322449b2fd | 45 | |
euxton | 1:75322449b2fd | 46 | MicroBitI2C i2c(I2C_SDA0, I2C_SCL0); |
euxton | 1:75322449b2fd | 47 | |
euxton | 1:75322449b2fd | 48 | void onButton(MicroBitEvent e) |
euxton | 1:75322449b2fd | 49 | { |
euxton | 1:75322449b2fd | 50 | if ((e.source == MICROBIT_ID_BUTTON_A) and (e.value == MICROBIT_BUTTON_EVT_DOWN)) { |
euxton | 1:75322449b2fd | 51 | inc_hr = inc_hr + 1; //increment by 1 for each press - hours |
euxton | 1:75322449b2fd | 52 | } |
euxton | 1:75322449b2fd | 53 | if ((e.source == MICROBIT_ID_BUTTON_B) and (e.value == MICROBIT_BUTTON_EVT_DOWN)) { |
euxton | 1:75322449b2fd | 54 | inc_mins = inc_mins + 1; //increment by 1 for each press - mins |
euxton | 1:75322449b2fd | 55 | } |
euxton | 1:75322449b2fd | 56 | } |
euxton | 1:75322449b2fd | 57 | |
euxton | 1:75322449b2fd | 58 | // helper functions to manipulate BCD and binary to integers |
euxton | 1:75322449b2fd | 59 | int bcd2dec(char r_char) |
euxton | 1:75322449b2fd | 60 | { |
euxton | 1:75322449b2fd | 61 | MSN = (r_char & 0xF0)/16; |
euxton | 1:75322449b2fd | 62 | LSN = r_char & 0x0F; |
euxton | 1:75322449b2fd | 63 | return(10*MSN + LSN); |
euxton | 1:75322449b2fd | 64 | } |
euxton | 1:75322449b2fd | 65 | char msn(char tim) |
euxton | 1:75322449b2fd | 66 | { |
euxton | 1:75322449b2fd | 67 | return (tim & 0xF0)/16; |
euxton | 1:75322449b2fd | 68 | } |
euxton | 1:75322449b2fd | 69 | char lsn(char tim) |
euxton | 1:75322449b2fd | 70 | { |
euxton | 1:75322449b2fd | 71 | return (tim & 0x0F); |
euxton | 1:75322449b2fd | 72 | } |
euxton | 1:75322449b2fd | 73 | |
euxton | 1:75322449b2fd | 74 | // Ensure RTCC is counting using the internal clk with ext xtal |
euxton | 1:75322449b2fd | 75 | void setConfig(void) |
euxton | 1:75322449b2fd | 76 | { |
euxton | 1:75322449b2fd | 77 | config_t[0] = 0x00; |
euxton | 1:75322449b2fd | 78 | config_t[1] = tim_read[0] | 0x80; // bitwise OR sets Start osc bit = 1 |
euxton | 1:75322449b2fd | 79 | config_t[2] = tim_read[1]; |
euxton | 1:75322449b2fd | 80 | config_t[3] = tim_read[2]; |
euxton | 1:75322449b2fd | 81 | config_t[4] = tim_read[3]; |
euxton | 1:75322449b2fd | 82 | config_t[5] = tim_read[4]; |
euxton | 1:75322449b2fd | 83 | config_t[6] = tim_read[5]; |
euxton | 1:75322449b2fd | 84 | config_t[7] = tim_read[6]; |
euxton | 1:75322449b2fd | 85 | config_t[8] = 0x00; // control b3 - extosc = 0 |
euxton | 1:75322449b2fd | 86 | } |
euxton | 1:75322449b2fd | 87 | int main() |
LancasterUniversity | 0:0041f35b0c4c | 88 | { |
euxton | 1:75322449b2fd | 89 | // Initialise the micro:bit runtime. |
euxton | 1:75322449b2fd | 90 | uBit.init(); |
euxton | 1:75322449b2fd | 91 | inc_hr = 0; |
euxton | 1:75322449b2fd | 92 | inc_mins = 0; |
LancasterUniversity | 0:0041f35b0c4c | 93 | |
euxton | 1:75322449b2fd | 94 | // Register to receive events when any buttons are clicked, including the A+B virtual button (both buttons at once). |
euxton | 1:75322449b2fd | 95 | uBit.messageBus.listen(MICROBIT_ID_BUTTON_A, MICROBIT_EVT_ANY, onButton); |
euxton | 1:75322449b2fd | 96 | uBit.messageBus.listen(MICROBIT_ID_BUTTON_B, MICROBIT_EVT_ANY, onButton); |
euxton | 1:75322449b2fd | 97 | |
euxton | 1:75322449b2fd | 98 | // Initialise microbit by reading the time from the RTCC module and adding control bits |
euxton | 1:75322449b2fd | 99 | // ST bit must be 1 Ext Osc must be 0 |
euxton | 1:75322449b2fd | 100 | // Write this once for set up if backup has battery |
euxton | 1:75322449b2fd | 101 | //i2c.write(addr, config_t, 9); //send time info only to set up |
euxton | 1:75322449b2fd | 102 | |
euxton | 1:75322449b2fd | 103 | // read stored time data |
euxton | 1:75322449b2fd | 104 | config_t[0] = 0x00; //reset pointer reg to '00' |
euxton | 1:75322449b2fd | 105 | |
euxton | 1:75322449b2fd | 106 | // Set up config to read the time and set the control bits |
euxton | 1:75322449b2fd | 107 | i2c.write(addr, config_t, 1); // write address 00 |
euxton | 1:75322449b2fd | 108 | i2c.read(addr, tim_read, 7); //read time ss mm hh from r1, r2, r3 |
euxton | 1:75322449b2fd | 109 | setConfig(); //puts RTCC data into config array from tim_read array |
euxton | 1:75322449b2fd | 110 | // write the config data |
euxton | 1:75322449b2fd | 111 | i2c.write(addr, config_t, 9); // write the config data back to the RTCC module |
euxton | 1:75322449b2fd | 112 | |
euxton | 1:75322449b2fd | 113 | while(1) { |
euxton | 1:75322449b2fd | 114 | // continuous loop to get time and display |
euxton | 1:75322449b2fd | 115 | // First Get the time |
euxton | 1:75322449b2fd | 116 | config_t[0] = 0x00; //reset pointer reg to '00' |
euxton | 1:75322449b2fd | 117 | i2c.write(addr, config_t, 1); |
euxton | 1:75322449b2fd | 118 | i2c.read(addr, tim_read, 3); //read time |
euxton | 1:75322449b2fd | 119 | |
euxton | 1:75322449b2fd | 120 | // display routine for seconds |
euxton | 1:75322449b2fd | 121 | secs = bcd2dec(tim_read[0]); |
euxton | 1:75322449b2fd | 122 | // Commented out seconds display as cannot set this |
euxton | 1:75322449b2fd | 123 | //disp_time[7] = 48+LSN; |
euxton | 1:75322449b2fd | 124 | //disp_time[6] = 48+MSN; |
euxton | 1:75322449b2fd | 125 | //disp_time[5] = 58; |
euxton | 1:75322449b2fd | 126 | disp_time[7] = 20; |
euxton | 1:75322449b2fd | 127 | disp_time[6] = 20; |
euxton | 1:75322449b2fd | 128 | disp_time[5] = 20; |
euxton | 1:75322449b2fd | 129 | |
euxton | 1:75322449b2fd | 130 | //Display and set mins |
euxton | 1:75322449b2fd | 131 | mins = bcd2dec(tim_read[1]); |
euxton | 1:75322449b2fd | 132 | disp_time[4] = 48+LSN; |
euxton | 1:75322449b2fd | 133 | disp_time[3] = 48+MSN; |
euxton | 1:75322449b2fd | 134 | disp_time[2] = 58; |
euxton | 1:75322449b2fd | 135 | // re-calculate mins section if button B is pressed |
euxton | 1:75322449b2fd | 136 | if (inc_mins > 0) { |
euxton | 1:75322449b2fd | 137 | mins = mins + inc_mins; |
euxton | 1:75322449b2fd | 138 | mins = mins%60; |
euxton | 1:75322449b2fd | 139 | ch_mins = 16*(mins/10) + mins%10; |
euxton | 1:75322449b2fd | 140 | MSN = msn(ch_mins); |
euxton | 1:75322449b2fd | 141 | LSN = lsn(ch_mins); |
euxton | 1:75322449b2fd | 142 | disp_time[4] = 48+LSN; |
euxton | 1:75322449b2fd | 143 | disp_time[3] = 48+MSN; |
euxton | 1:75322449b2fd | 144 | tim_read[1] = ch_mins; |
euxton | 1:75322449b2fd | 145 | inc_mins = 0; |
euxton | 1:75322449b2fd | 146 | //write the data back to RTCC |
euxton | 1:75322449b2fd | 147 | setConfig(); |
euxton | 1:75322449b2fd | 148 | i2c.write(addr, config_t, 9); |
euxton | 1:75322449b2fd | 149 | } |
euxton | 1:75322449b2fd | 150 | |
euxton | 1:75322449b2fd | 151 | //Display and set hours |
euxton | 1:75322449b2fd | 152 | hrs = bcd2dec(tim_read[2]); |
euxton | 1:75322449b2fd | 153 | disp_time[1] = 48+LSN; |
euxton | 1:75322449b2fd | 154 | disp_time[0] = 48+MSN; |
euxton | 1:75322449b2fd | 155 | // re-calculate hrs section if button A is pressed |
euxton | 1:75322449b2fd | 156 | if (inc_hr > 0) { |
euxton | 1:75322449b2fd | 157 | hrs = hrs + inc_hr; |
euxton | 1:75322449b2fd | 158 | hrs = hrs%24; |
euxton | 1:75322449b2fd | 159 | ch_hrs = 16*(hrs/10) + hrs%10; |
euxton | 1:75322449b2fd | 160 | MSN = msn(ch_hrs); |
euxton | 1:75322449b2fd | 161 | LSN = lsn(ch_hrs); |
euxton | 1:75322449b2fd | 162 | disp_time[1] = 48+LSN; |
euxton | 1:75322449b2fd | 163 | disp_time[0] = 48+MSN; |
euxton | 1:75322449b2fd | 164 | tim_read[2] = ch_hrs; |
euxton | 1:75322449b2fd | 165 | inc_hr = 0; |
euxton | 1:75322449b2fd | 166 | //write the data back to RTCC |
euxton | 1:75322449b2fd | 167 | setConfig(); |
euxton | 1:75322449b2fd | 168 | i2c.write(addr, config_t, 9); |
euxton | 1:75322449b2fd | 169 | } |
euxton | 1:75322449b2fd | 170 | |
euxton | 1:75322449b2fd | 171 | // create the display string and scroll it |
euxton | 1:75322449b2fd | 172 | ManagedString s = disp_time; |
euxton | 1:75322449b2fd | 173 | uBit.display.scroll(s); |
euxton | 1:75322449b2fd | 174 | uBit.sleep(50); |
euxton | 1:75322449b2fd | 175 | |
euxton | 1:75322449b2fd | 176 | } |
euxton | 1:75322449b2fd | 177 | |
euxton | 1:75322449b2fd | 178 | |
LancasterUniversity | 0:0041f35b0c4c | 179 | |
LancasterUniversity | 0:0041f35b0c4c | 180 | // If main exits, there may still be other fibers running or registered event handlers etc. |
LancasterUniversity | 0:0041f35b0c4c | 181 | // Simply release this fiber, which will mean we enter the scheduler. Worse case, we then |
LancasterUniversity | 0:0041f35b0c4c | 182 | // sit in the idle task forever, in a power efficient sleep. |
LancasterUniversity | 0:0041f35b0c4c | 183 | release_fiber(); |
euxton | 1:75322449b2fd | 184 | } // end of main |
euxton | 1:75322449b2fd | 185 |