Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: TextLCD nRF24L01P mbed
main.cpp@8:0de75e0480aa, 2017-01-12 (annotated)
- Committer:
- jackmax
- Date:
- Thu Jan 12 16:43:57 2017 +0000
- Revision:
- 8:0de75e0480aa
- Parent:
- 6:19012a85ce35
- Child:
- 9:53da36425601
Added wireless communication with remote sensor.
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| jackmax | 6:19012a85ce35 | 1 | #include "mbed.h" |
| jackmax | 6:19012a85ce35 | 2 | #include "rtos.h" |
| jackmax | 6:19012a85ce35 | 3 | #include "TextLCD.h" |
| jackmax | 6:19012a85ce35 | 4 | #include "custom-chars.h" |
| jackmax | 8:0de75e0480aa | 5 | #include "nRF24L01P.h" |
| jackmax | 8:0de75e0480aa | 6 | |
| jackmax | 6:19012a85ce35 | 7 | // Host PC Communication channels |
| jackmax | 6:19012a85ce35 | 8 | Serial pc(USBTX, USBRX); // tx, rx |
| jackmax | 6:19012a85ce35 | 9 | |
| jackmax | 6:19012a85ce35 | 10 | I2C i2c_lcd(D5,D7); // SDA, SCL pins. Change if necessary |
| jackmax | 6:19012a85ce35 | 11 | TextLCD_I2C lcd(&i2c_lcd, 0x4E, TextLCD::LCD16x2); // I2C exp: I2C bus, PCF8574 Slaveaddress, LCD Type |
| jackmax | 6:19012a85ce35 | 12 | |
| jackmax | 6:19012a85ce35 | 13 | //Light sensor |
| jackmax | 6:19012a85ce35 | 14 | AnalogIn light_sensor(A1); |
| jackmax | 6:19012a85ce35 | 15 | |
| jackmax | 8:0de75e0480aa | 16 | //2.4 GHz radio |
| jackmax | 8:0de75e0480aa | 17 | #define RX_ADDRESS ((unsigned long long) 0xABCDEF00) |
| jackmax | 8:0de75e0480aa | 18 | #define TX_ADDRESS ((unsigned long long) 0xABCDEF01) |
| jackmax | 8:0de75e0480aa | 19 | #define TRANSFER_SIZE 32 |
| jackmax | 8:0de75e0480aa | 20 | |
| jackmax | 8:0de75e0480aa | 21 | nRF24L01P radio(PB_15, PB_14, PB_13, PB_12, PB_1, PB_2); |
| jackmax | 8:0de75e0480aa | 22 | |
| jackmax | 8:0de75e0480aa | 23 | void initRadio(int channel, int power, int datarate){ |
| jackmax | 8:0de75e0480aa | 24 | radio.powerDown(); |
| jackmax | 8:0de75e0480aa | 25 | radio.powerUp(); |
| jackmax | 8:0de75e0480aa | 26 | |
| jackmax | 8:0de75e0480aa | 27 | radio.setAirDataRate(datarate); |
| jackmax | 8:0de75e0480aa | 28 | radio.setRfOutputPower(power); |
| jackmax | 8:0de75e0480aa | 29 | radio.setRfFrequency(NRF24L01P_MIN_RF_FREQUENCY + 4 * channel); |
| jackmax | 8:0de75e0480aa | 30 | |
| jackmax | 8:0de75e0480aa | 31 | radio.setCrcWidth(NRF24L01P_CRC_8_BIT); |
| jackmax | 8:0de75e0480aa | 32 | radio.enableAutoAcknowledge(NRF24L01P_PIPE_P0); |
| jackmax | 8:0de75e0480aa | 33 | radio.enableAutoAcknowledge(NRF24L01P_PIPE_P1); |
| jackmax | 8:0de75e0480aa | 34 | radio.enableAutoRetransmit(0x0F, 0x0F); |
| jackmax | 8:0de75e0480aa | 35 | |
| jackmax | 8:0de75e0480aa | 36 | radio.setTxAddress(TX_ADDRESS, 4); |
| jackmax | 8:0de75e0480aa | 37 | radio.setRxAddress(TX_ADDRESS, 4, NRF24L01P_PIPE_P0); |
| jackmax | 8:0de75e0480aa | 38 | |
| jackmax | 8:0de75e0480aa | 39 | radio.setRxAddress(RX_ADDRESS, 4, NRF24L01P_PIPE_P1); |
| jackmax | 8:0de75e0480aa | 40 | |
| jackmax | 8:0de75e0480aa | 41 | // Display the (default) setup of the nRF24L01+ chip |
| jackmax | 8:0de75e0480aa | 42 | pc.printf( "nRF24L01+ Frequency : %d MHz\r\n", radio.getRfFrequency() ); |
| jackmax | 8:0de75e0480aa | 43 | pc.printf( "nRF24L01+ Output power : %d dBm\r\n", radio.getRfOutputPower() ); |
| jackmax | 8:0de75e0480aa | 44 | pc.printf( "nRF24L01+ Data Rate : %d kbps\r\n", radio.getAirDataRate() ); |
| jackmax | 8:0de75e0480aa | 45 | pc.printf( "nRF24L01+ TX Address : 0x%010llX\r\n", radio.getTxAddress() ); |
| jackmax | 8:0de75e0480aa | 46 | pc.printf( "nRF24L01+ RX0 Address : 0x%010llX\r\n", radio.getRxAddress(NRF24L01P_PIPE_P0) ); |
| jackmax | 8:0de75e0480aa | 47 | pc.printf( "nRF24L01+ RX1 Address : 0x%010llX\r\n", radio.getRxAddress(NRF24L01P_PIPE_P1) ); |
| jackmax | 8:0de75e0480aa | 48 | |
| jackmax | 8:0de75e0480aa | 49 | |
| jackmax | 8:0de75e0480aa | 50 | radio.setTransferSize(TRANSFER_SIZE, NRF24L01P_PIPE_P0); |
| jackmax | 8:0de75e0480aa | 51 | radio.setTransferSize(TRANSFER_SIZE, NRF24L01P_PIPE_P1); |
| jackmax | 8:0de75e0480aa | 52 | |
| jackmax | 8:0de75e0480aa | 53 | radio.setReceiveMode(); |
| jackmax | 8:0de75e0480aa | 54 | radio.enable(); |
| jackmax | 8:0de75e0480aa | 55 | }; |
| jackmax | 8:0de75e0480aa | 56 | |
| jackmax | 8:0de75e0480aa | 57 | //Display |
| jackmax | 6:19012a85ce35 | 58 | void backlightTimeout(void const *arg); |
| jackmax | 6:19012a85ce35 | 59 | RtosTimer backlightTimer(&backlightTimeout, osTimerPeriodic, (void*)0); |
| jackmax | 6:19012a85ce35 | 60 | |
| jackmax | 6:19012a85ce35 | 61 | class Display{ |
| jackmax | 6:19012a85ce35 | 62 | public: |
| jackmax | 6:19012a85ce35 | 63 | int wifi_on; |
| jackmax | 6:19012a85ce35 | 64 | int alarm_on; |
| jackmax | 6:19012a85ce35 | 65 | int sync_in_progress; |
| jackmax | 6:19012a85ce35 | 66 | int wireless_in_progress; |
| jackmax | 6:19012a85ce35 | 67 | int frame; |
| jackmax | 6:19012a85ce35 | 68 | |
| jackmax | 6:19012a85ce35 | 69 | time_t seconds; |
| jackmax | 6:19012a85ce35 | 70 | char time_str[9]; |
| jackmax | 6:19012a85ce35 | 71 | char date_str[9]; |
| jackmax | 6:19012a85ce35 | 72 | |
| jackmax | 6:19012a85ce35 | 73 | static const int backlightTime = 5000; |
| jackmax | 6:19012a85ce35 | 74 | int backlightState; |
| jackmax | 6:19012a85ce35 | 75 | Display() |
| jackmax | 6:19012a85ce35 | 76 | { |
| jackmax | 6:19012a85ce35 | 77 | wifi_on = 0; |
| jackmax | 6:19012a85ce35 | 78 | alarm_on = 0; |
| jackmax | 6:19012a85ce35 | 79 | sync_in_progress = 0; |
| jackmax | 6:19012a85ce35 | 80 | wireless_in_progress = 0; |
| jackmax | 6:19012a85ce35 | 81 | frame = 0; |
| jackmax | 6:19012a85ce35 | 82 | backlightState = 0; |
| jackmax | 6:19012a85ce35 | 83 | |
| jackmax | 6:19012a85ce35 | 84 | lcd.setCursor(TextLCD::CurOff_BlkOff); |
| jackmax | 6:19012a85ce35 | 85 | lcd.setUDC(C_ALRM, cc_dzwonek); |
| jackmax | 6:19012a85ce35 | 86 | lcd.setUDC(C_WIFI, cc_wifi); |
| jackmax | 6:19012a85ce35 | 87 | lcd.setUDC(C_WLC , cc_wireless); |
| jackmax | 6:19012a85ce35 | 88 | } |
| jackmax | 6:19012a85ce35 | 89 | |
| jackmax | 6:19012a85ce35 | 90 | void backlightOff(){ |
| jackmax | 6:19012a85ce35 | 91 | lcd.setBacklight(TextLCD::LightOff); |
| jackmax | 6:19012a85ce35 | 92 | backlightState = 0; |
| jackmax | 6:19012a85ce35 | 93 | } |
| jackmax | 6:19012a85ce35 | 94 | |
| jackmax | 6:19012a85ce35 | 95 | void backlightOn(){ |
| jackmax | 6:19012a85ce35 | 96 | lcd.setBacklight(TextLCD::LightOn); |
| jackmax | 6:19012a85ce35 | 97 | backlightState = 1; |
| jackmax | 6:19012a85ce35 | 98 | backlightTimer.start(backlightTime); |
| jackmax | 6:19012a85ce35 | 99 | } |
| jackmax | 6:19012a85ce35 | 100 | |
| jackmax | 6:19012a85ce35 | 101 | void update(){ |
| jackmax | 6:19012a85ce35 | 102 | //Top row of display |
| jackmax | 6:19012a85ce35 | 103 | char ico1 = ' '; |
| jackmax | 6:19012a85ce35 | 104 | char ico2 = wireless_in_progress ? (frame % 2 ? C_WLC : ' ' ) : ' '; |
| jackmax | 6:19012a85ce35 | 105 | char ico3 = C_ALRM; |
| jackmax | 6:19012a85ce35 | 106 | int ah=85, am=84; |
| jackmax | 6:19012a85ce35 | 107 | |
| jackmax | 6:19012a85ce35 | 108 | time_t seconds_now = time(NULL); |
| jackmax | 6:19012a85ce35 | 109 | if (seconds_now != seconds) { |
| jackmax | 6:19012a85ce35 | 110 | seconds = seconds_now; |
| jackmax | 6:19012a85ce35 | 111 | strftime(time_str, 9, "%X", localtime(&seconds)); |
| jackmax | 6:19012a85ce35 | 112 | strftime(date_str, 9, "%x", localtime(&seconds)); |
| jackmax | 6:19012a85ce35 | 113 | } |
| jackmax | 6:19012a85ce35 | 114 | |
| jackmax | 6:19012a85ce35 | 115 | lcd.locate(0,0); //Put in top row |
| jackmax | 6:19012a85ce35 | 116 | lcd.printf("%s%c%c%c%02d:%02d",time_str,ico1,ico2,ico3,ah,am); |
| jackmax | 6:19012a85ce35 | 117 | |
| jackmax | 6:19012a85ce35 | 118 | lcd.locate(0,1); //Put in bottom row |
| jackmax | 6:19012a85ce35 | 119 | if (sync_in_progress) { |
| jackmax | 6:19012a85ce35 | 120 | lcd.printf("Synchronizacja.."); |
| jackmax | 6:19012a85ce35 | 121 | } |
| jackmax | 6:19012a85ce35 | 122 | else { |
| jackmax | 6:19012a85ce35 | 123 | if (frame % 60 < 30) { |
| jackmax | 6:19012a85ce35 | 124 | lcd.printf("SmartAlarm+ Pro "); |
| jackmax | 6:19012a85ce35 | 125 | } |
| jackmax | 6:19012a85ce35 | 126 | else { |
| jackmax | 6:19012a85ce35 | 127 | lcd.printf(" %08s ", date_str); |
| jackmax | 6:19012a85ce35 | 128 | } |
| jackmax | 6:19012a85ce35 | 129 | } |
| jackmax | 6:19012a85ce35 | 130 | frame++; |
| jackmax | 6:19012a85ce35 | 131 | } |
| jackmax | 6:19012a85ce35 | 132 | }; |
| jackmax | 6:19012a85ce35 | 133 | |
| jackmax | 6:19012a85ce35 | 134 | Display disp; |
| jackmax | 6:19012a85ce35 | 135 | |
| jackmax | 6:19012a85ce35 | 136 | //Handling user button presses |
| jackmax | 6:19012a85ce35 | 137 | InterruptIn button(D6); |
| jackmax | 6:19012a85ce35 | 138 | int userButtonLongPress = 300; //Time in ms; threshold for long press |
| jackmax | 6:19012a85ce35 | 139 | Timer userButtonTimer; |
| jackmax | 6:19012a85ce35 | 140 | |
| jackmax | 6:19012a85ce35 | 141 | int userButtonPressed = 0, userButtonReleased = 0, backlightTimedOut = 0; |
| jackmax | 6:19012a85ce35 | 142 | |
| jackmax | 6:19012a85ce35 | 143 | void userButtonPress(){ |
| jackmax | 6:19012a85ce35 | 144 | userButtonPressed = 1; |
| jackmax | 6:19012a85ce35 | 145 | } |
| jackmax | 6:19012a85ce35 | 146 | |
| jackmax | 6:19012a85ce35 | 147 | void userButtonRelease(){ |
| jackmax | 6:19012a85ce35 | 148 | userButtonReleased = 1; |
| jackmax | 6:19012a85ce35 | 149 | } |
| jackmax | 6:19012a85ce35 | 150 | |
| jackmax | 6:19012a85ce35 | 151 | void backlightTimeout(void const *arg){ |
| jackmax | 6:19012a85ce35 | 152 | backlightTimedOut = 1; |
| jackmax | 6:19012a85ce35 | 153 | } |
| jackmax | 6:19012a85ce35 | 154 | |
| jackmax | 8:0de75e0480aa | 155 | //TODO: I don't think it needs to be in a separate thread, |
| jackmax | 8:0de75e0480aa | 156 | //we probably can just put it into the main loop. |
| jackmax | 8:0de75e0480aa | 157 | void radio_recv(void const* args){ |
| jackmax | 8:0de75e0480aa | 158 | char rxData[TRANSFER_SIZE+1]; |
| jackmax | 8:0de75e0480aa | 159 | while (1) { |
| jackmax | 8:0de75e0480aa | 160 | int rx_bytes=0; |
| jackmax | 8:0de75e0480aa | 161 | |
| jackmax | 8:0de75e0480aa | 162 | if(radio.readable(NRF24L01P_PIPE_P1)){ |
| jackmax | 8:0de75e0480aa | 163 | rx_bytes = radio.read(NRF24L01P_PIPE_P1, rxData, TRANSFER_SIZE); |
| jackmax | 8:0de75e0480aa | 164 | rxData[TRANSFER_SIZE] = '\0'; |
| jackmax | 8:0de75e0480aa | 165 | pc.printf("Received %d >>%s<<\r\n",rx_bytes, rxData); |
| jackmax | 8:0de75e0480aa | 166 | } |
| jackmax | 8:0de75e0480aa | 167 | |
| jackmax | 8:0de75e0480aa | 168 | } |
| jackmax | 8:0de75e0480aa | 169 | } |
| jackmax | 8:0de75e0480aa | 170 | |
| jackmax | 6:19012a85ce35 | 171 | Ticker display_update_ticker; |
| jackmax | 6:19012a85ce35 | 172 | int main() { |
| jackmax | 6:19012a85ce35 | 173 | set_time(1256729737); //DEBUG: Set RTC time to Wed, 28 Oct 2009 11:35:37 |
| jackmax | 6:19012a85ce35 | 174 | //Initialization |
| jackmax | 6:19012a85ce35 | 175 | disp.backlightOn(); |
| jackmax | 6:19012a85ce35 | 176 | button.rise(&userButtonPress); |
| jackmax | 6:19012a85ce35 | 177 | button.fall(&userButtonRelease); |
| jackmax | 6:19012a85ce35 | 178 | |
| jackmax | 8:0de75e0480aa | 179 | |
| jackmax | 8:0de75e0480aa | 180 | initRadio(6, NRF24L01P_TX_PWR_ZERO_DB, NRF24L01P_DATARATE_250_KBPS); |
| jackmax | 8:0de75e0480aa | 181 | Thread radio_thread(radio_recv); |
| jackmax | 8:0de75e0480aa | 182 | |
| jackmax | 6:19012a85ce35 | 183 | while (1){ |
| jackmax | 6:19012a85ce35 | 184 | pc.printf("ok\r\n"); |
| jackmax | 6:19012a85ce35 | 185 | |
| jackmax | 8:0de75e0480aa | 186 | //Handling button presses |
| jackmax | 6:19012a85ce35 | 187 | if (userButtonPressed) { |
| jackmax | 6:19012a85ce35 | 188 | userButtonPressed = 0; |
| jackmax | 6:19012a85ce35 | 189 | userButtonTimer.reset(); |
| jackmax | 6:19012a85ce35 | 190 | userButtonTimer.start(); |
| jackmax | 6:19012a85ce35 | 191 | } |
| jackmax | 6:19012a85ce35 | 192 | |
| jackmax | 6:19012a85ce35 | 193 | if (userButtonReleased) { |
| jackmax | 6:19012a85ce35 | 194 | userButtonReleased = 0; |
| jackmax | 6:19012a85ce35 | 195 | userButtonTimer.stop(); |
| jackmax | 6:19012a85ce35 | 196 | if (userButtonTimer.read_ms() > userButtonLongPress){ |
| jackmax | 6:19012a85ce35 | 197 | pc.printf("User button long pressed"); |
| jackmax | 6:19012a85ce35 | 198 | disp.backlightOff(); |
| jackmax | 6:19012a85ce35 | 199 | } |
| jackmax | 6:19012a85ce35 | 200 | else { |
| jackmax | 6:19012a85ce35 | 201 | pc.printf("User button short pressed"); |
| jackmax | 6:19012a85ce35 | 202 | disp.backlightOn(); |
| jackmax | 6:19012a85ce35 | 203 | } |
| jackmax | 6:19012a85ce35 | 204 | } |
| jackmax | 6:19012a85ce35 | 205 | |
| jackmax | 8:0de75e0480aa | 206 | //Handling backlight |
| jackmax | 6:19012a85ce35 | 207 | if (backlightTimedOut){ |
| jackmax | 6:19012a85ce35 | 208 | backlightTimedOut = 0; |
| jackmax | 6:19012a85ce35 | 209 | disp.backlightOff(); |
| jackmax | 6:19012a85ce35 | 210 | } |
| jackmax | 6:19012a85ce35 | 211 | |
| jackmax | 8:0de75e0480aa | 212 | //Updating display |
| jackmax | 6:19012a85ce35 | 213 | disp.update(); |
| jackmax | 8:0de75e0480aa | 214 | |
| jackmax | 6:19012a85ce35 | 215 | Thread::wait(100); |
| jackmax | 6:19012a85ce35 | 216 | }; |
| jackmax | 6:19012a85ce35 | 217 | } |
| jackmax | 6:19012a85ce35 | 218 | |
| jackmax | 6:19012a85ce35 | 219 | |
| jackmax | 6:19012a85ce35 | 220 |

