JNP3 SmartAlarm / Mbed 2 deprecated budzik

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);
    };
}