BLE Lightning sensor for Nordic NRF51822 based module
Dependencies: AS3935 AS3935_ext BLE_API mbed nRF51822 nrf51_rtc
Diff: main.cpp
- Revision:
- 0:371bcac81ea2
- Child:
- 1:a4119049dd99
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Thu Aug 27 10:14:50 2015 +0000 @@ -0,0 +1,165 @@ +/* +This example code shows one way of creating a real time clock for the nRF51 without interfering with the mbed library functions + +Two methods are created to replace the similarly named C routines: rtc.time and rtc.set_time. +If the rtc.time method isn't called frequently (< 512 seconds between calls), a ticker (from the mbed library) is required +to keep the time updated. + +In this example, LED2 toggles and the time is printed when button1 is pushed. LED1 will toggle when the time is periodically updated. + +references: + -- see NRF_RTC_Type in nrf51.h + (e.g.: http://developer.mbed.org/users/mbed_official/code/mbed-src/file/12a9a5f8fea0/targets/cmsis/TARGET_NORDIC/TARGET_MCU_NRF51822/nrf51.h) + -- see "nRF51 Series Reference Manual" chapter on Real Time Counter (chapter 19 in V3.0) +Note: RTC2 does not exist, despite what the nrf51 reference manual (V3.0) claims. The other RTCs (0/1) are used by various other libraries, +so you can read, but don't write! + +*/ + +#include "mbed.h" +#include "nrf51_rtc.h" +#include "AS3935_ext.h" + +AS3935_ext Lightning(I2C_SDA0,I2C_SCL0,0x00,P0_23); +InterruptIn IntLightning(P0_23); //IRQ AS3935 + +// used for the example only, not required for rtc use +DigitalOut rtc_update_led(LED1); // toggle when update_rtc is called +DigitalOut button_push_led(LED2); // toggle when button1 is pushed +DigitalIn button1(BUTTON1); // used to trigger the time report +InterruptIn button1Press(BUTTON1); +Serial pc(USBTX,USBRX); + + +time_t example_time() { + // set an intial time + // ...not really necessary for this example, but it beats setting it to 0 or some non-obvious large integer (# of seconds since 1/1/1970) + time_t rawtime=0; + + struct tm * init_timeinfo; + + // initialize time + init_timeinfo = localtime(&rawtime); // note: must initialize the struct with this before trying to set components + // ...else code goes into the weeds!! + init_timeinfo->tm_sec = 0; + init_timeinfo->tm_min = 0; + init_timeinfo->tm_hour = 0; + init_timeinfo->tm_mon = 0; + init_timeinfo->tm_mday = 1; + init_timeinfo->tm_year = 0; + + char date[24]; + strftime(date,sizeof(date),"%H:%M:%S on %m/%d/%G",init_timeinfo); + pc.printf("Initial time set is %s.\r\n",date); + + // compute the proper value for time in time_t type + rawtime = mktime(init_timeinfo); + return rawtime; +} +void print_time() { + // called when a button is pushed, this prints the current time to the USB-connected console + button_push_led = !button_push_led; + + time_t rawtime=rtc.time(); + + // massage the time into a human-friendly format for printing + struct tm * timeinfo; + timeinfo = localtime(&rawtime); + char date[24]; + strftime(date,sizeof(date),"%H:%M:%S on %m/%d/%G",timeinfo); + pc.printf("The current time is %s.(%d)\r\n",date,rawtime); +} + +// (probably) required for rtc use +void update_rtc() { + // for use as interrupt routine, to insure that RTC is updated periodically + // ...if rtc is not read before the underlying counter rolls over (typically 512 seconds), the RTC value will be wrong + // ...ideally this would be done as part of the nrf51_rtc method, but I couldn't get it to behave (see nrf51_rtc.cpp for details) + rtc.time(); + rtc_update_led = !rtc_update_led; + // print_time(); +} + +void DetectLightning() +{ + char OriginInt; + time_t rawtime=rtc.time(); + struct tm * timeinfo; + timeinfo = localtime(&rawtime); + char date[24]; + int distance; + + strftime(date,sizeof(date),"%H:%M:%S on %m/%d/%G",timeinfo); + + wait_ms(2); //on attend 2ms préconisation constructeur + OriginInt = Lightning.interruptSource(); + distance = Lightning.lightningDistanceKm(); + + if (OriginInt == 1) { + pc.printf("%24s : Noise level too high. %d km\r\n",date,distance); + } + if (OriginInt == 4) { + pc.printf("%24s : Disturber detected. %d km\r\n",date,distance); + } + if (OriginInt == 8) { + distance = Lightning.lightningDistanceKm(); + pc.printf("%24s : Lightning interrupt %d km\r\n",date,distance); + } +} + + +int main(void) +{ + rtc_update_led=0; + button_push_led=0; + int hz=0; + + //initialisations + pc.printf("reset\r\n"); + Lightning.reset(); + pc.printf("setTuneCap as 5\r\n"); + Lightning.setTuneCap(5); // Tuning Parameter + pc.printf("powerup\r\n"); + Lightning.powerUp(); + pc.printf("setIndoors\r\n"); + Lightning.setIndoors(); // Set Device into Indoor mode + + pc.printf("Auto Calibration Start\r\n"); + float minerr = 100; + int fincap = 7; + for(int i=0;i<16;i++) { + Lightning.setTuneCap(i); // Tuning Parameter + hz = Lightning.MeasureLCOFreq(); + float err = (hz-500000.)/500000.*100.; + pc.printf("%d : hz=%10d Hz (%5.2f%%)\r\n",i,hz,err); + if ( abs(err) < minerr ) { + minerr = abs(err); + fincap = i; + } + } + Lightning.setTuneCap(fincap); // Tuning Parameter + wait_ms(100); + hz = Lightning.MeasureLCOFreq(); + float err = (hz-500000.)/500000.*100.; + pc.printf("Final %d : hz=%10d Hz (%5.2f%%)\r\n",fincap,hz,err); + + pc.printf("Auto Calibration finished\r\n"); + + // user selectable, any time < 512 seconds is OK + #define PERIODIC_UPDATE 1 + Ticker rtc_ticker; + rtc_ticker.attach(&update_rtc, PERIODIC_UPDATE); // update the time regularly + + time_t initial_time = example_time(); + rtc.set_time(initial_time); + + button1Press.fall(&print_time); // when button1 is pressed, this calls rtc.time() and prints it + + // Lightning.setIndoors(); // Set Device into Indoor mode + Lightning.setOutdoors(); // Set Device into Outdoor mode + IntLightning.rise(&DetectLightning); + + while (true) { + sleep(); + } +}