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
- Committer:
- jackmax
- Date:
- 2017-01-12
- Revision:
- 8:0de75e0480aa
- Parent:
- 6:19012a85ce35
- Child:
- 9:53da36425601
File content as of revision 8:0de75e0480aa:
#include "mbed.h"
#include "rtos.h"
#include "TextLCD.h"
#include "custom-chars.h"
#include "nRF24L01P.h"
// Host PC Communication channels
Serial pc(USBTX, USBRX); // tx, rx
I2C i2c_lcd(D5,D7); // SDA, SCL pins. Change if necessary
TextLCD_I2C lcd(&i2c_lcd, 0x4E, TextLCD::LCD16x2); // I2C exp: I2C bus, PCF8574 Slaveaddress, LCD Type
//Light sensor
AnalogIn light_sensor(A1);
//2.4 GHz radio
#define RX_ADDRESS ((unsigned long long) 0xABCDEF00)
#define TX_ADDRESS ((unsigned long long) 0xABCDEF01)
#define TRANSFER_SIZE 32
nRF24L01P radio(PB_15, PB_14, PB_13, PB_12, PB_1, PB_2);
void initRadio(int channel, int power, int datarate){
radio.powerDown();
radio.powerUp();
radio.setAirDataRate(datarate);
radio.setRfOutputPower(power);
radio.setRfFrequency(NRF24L01P_MIN_RF_FREQUENCY + 4 * channel);
radio.setCrcWidth(NRF24L01P_CRC_8_BIT);
radio.enableAutoAcknowledge(NRF24L01P_PIPE_P0);
radio.enableAutoAcknowledge(NRF24L01P_PIPE_P1);
radio.enableAutoRetransmit(0x0F, 0x0F);
radio.setTxAddress(TX_ADDRESS, 4);
radio.setRxAddress(TX_ADDRESS, 4, NRF24L01P_PIPE_P0);
radio.setRxAddress(RX_ADDRESS, 4, NRF24L01P_PIPE_P1);
// Display the (default) setup of the nRF24L01+ chip
pc.printf( "nRF24L01+ Frequency : %d MHz\r\n", radio.getRfFrequency() );
pc.printf( "nRF24L01+ Output power : %d dBm\r\n", radio.getRfOutputPower() );
pc.printf( "nRF24L01+ Data Rate : %d kbps\r\n", radio.getAirDataRate() );
pc.printf( "nRF24L01+ TX Address : 0x%010llX\r\n", radio.getTxAddress() );
pc.printf( "nRF24L01+ RX0 Address : 0x%010llX\r\n", radio.getRxAddress(NRF24L01P_PIPE_P0) );
pc.printf( "nRF24L01+ RX1 Address : 0x%010llX\r\n", radio.getRxAddress(NRF24L01P_PIPE_P1) );
radio.setTransferSize(TRANSFER_SIZE, NRF24L01P_PIPE_P0);
radio.setTransferSize(TRANSFER_SIZE, NRF24L01P_PIPE_P1);
radio.setReceiveMode();
radio.enable();
};
//Display
void backlightTimeout(void const *arg);
RtosTimer backlightTimer(&backlightTimeout, osTimerPeriodic, (void*)0);
class Display{
public:
int wifi_on;
int alarm_on;
int sync_in_progress;
int wireless_in_progress;
int frame;
time_t seconds;
char time_str[9];
char date_str[9];
static const int backlightTime = 5000;
int backlightState;
Display()
{
wifi_on = 0;
alarm_on = 0;
sync_in_progress = 0;
wireless_in_progress = 0;
frame = 0;
backlightState = 0;
lcd.setCursor(TextLCD::CurOff_BlkOff);
lcd.setUDC(C_ALRM, cc_dzwonek);
lcd.setUDC(C_WIFI, cc_wifi);
lcd.setUDC(C_WLC , cc_wireless);
}
void backlightOff(){
lcd.setBacklight(TextLCD::LightOff);
backlightState = 0;
}
void backlightOn(){
lcd.setBacklight(TextLCD::LightOn);
backlightState = 1;
backlightTimer.start(backlightTime);
}
void update(){
//Top row of display
char ico1 = ' ';
char ico2 = wireless_in_progress ? (frame % 2 ? C_WLC : ' ' ) : ' ';
char ico3 = C_ALRM;
int ah=85, am=84;
time_t seconds_now = time(NULL);
if (seconds_now != seconds) {
seconds = seconds_now;
strftime(time_str, 9, "%X", localtime(&seconds));
strftime(date_str, 9, "%x", localtime(&seconds));
}
lcd.locate(0,0); //Put in top row
lcd.printf("%s%c%c%c%02d:%02d",time_str,ico1,ico2,ico3,ah,am);
lcd.locate(0,1); //Put in bottom row
if (sync_in_progress) {
lcd.printf("Synchronizacja..");
}
else {
if (frame % 60 < 30) {
lcd.printf("SmartAlarm+ Pro ");
}
else {
lcd.printf(" %08s ", date_str);
}
}
frame++;
}
};
Display disp;
//Handling user button presses
InterruptIn button(D6);
int userButtonLongPress = 300; //Time in ms; threshold for long press
Timer userButtonTimer;
int userButtonPressed = 0, userButtonReleased = 0, backlightTimedOut = 0;
void userButtonPress(){
userButtonPressed = 1;
}
void userButtonRelease(){
userButtonReleased = 1;
}
void backlightTimeout(void const *arg){
backlightTimedOut = 1;
}
//TODO: I don't think it needs to be in a separate thread,
//we probably can just put it into the main loop.
void radio_recv(void const* args){
char rxData[TRANSFER_SIZE+1];
while (1) {
int rx_bytes=0;
if(radio.readable(NRF24L01P_PIPE_P1)){
rx_bytes = radio.read(NRF24L01P_PIPE_P1, rxData, TRANSFER_SIZE);
rxData[TRANSFER_SIZE] = '\0';
pc.printf("Received %d >>%s<<\r\n",rx_bytes, rxData);
}
}
}
Ticker display_update_ticker;
int main() {
set_time(1256729737); //DEBUG: Set RTC time to Wed, 28 Oct 2009 11:35:37
//Initialization
disp.backlightOn();
button.rise(&userButtonPress);
button.fall(&userButtonRelease);
initRadio(6, NRF24L01P_TX_PWR_ZERO_DB, NRF24L01P_DATARATE_250_KBPS);
Thread radio_thread(radio_recv);
while (1){
pc.printf("ok\r\n");
//Handling button presses
if (userButtonPressed) {
userButtonPressed = 0;
userButtonTimer.reset();
userButtonTimer.start();
}
if (userButtonReleased) {
userButtonReleased = 0;
userButtonTimer.stop();
if (userButtonTimer.read_ms() > userButtonLongPress){
pc.printf("User button long pressed");
disp.backlightOff();
}
else {
pc.printf("User button short pressed");
disp.backlightOn();
}
}
//Handling backlight
if (backlightTimedOut){
backlightTimedOut = 0;
disp.backlightOff();
}
//Updating display
disp.update();
Thread::wait(100);
};
}

