BLE Lightning sensor for Nordic NRF51822 based module

Dependencies:   AS3935 AS3935_ext BLE_API mbed nRF51822 nrf51_rtc

Committer:
takafuminaka
Date:
Thu Aug 27 10:14:50 2015 +0000
Revision:
0:371bcac81ea2
Child:
1:a4119049dd99
Intermediate product.; (Just UART I/O verrsion)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
takafuminaka 0:371bcac81ea2 1 /*
takafuminaka 0:371bcac81ea2 2 This example code shows one way of creating a real time clock for the nRF51 without interfering with the mbed library functions
takafuminaka 0:371bcac81ea2 3
takafuminaka 0:371bcac81ea2 4 Two methods are created to replace the similarly named C routines: rtc.time and rtc.set_time.
takafuminaka 0:371bcac81ea2 5 If the rtc.time method isn't called frequently (< 512 seconds between calls), a ticker (from the mbed library) is required
takafuminaka 0:371bcac81ea2 6 to keep the time updated.
takafuminaka 0:371bcac81ea2 7
takafuminaka 0:371bcac81ea2 8 In this example, LED2 toggles and the time is printed when button1 is pushed. LED1 will toggle when the time is periodically updated.
takafuminaka 0:371bcac81ea2 9
takafuminaka 0:371bcac81ea2 10 references:
takafuminaka 0:371bcac81ea2 11 -- see NRF_RTC_Type in nrf51.h
takafuminaka 0:371bcac81ea2 12 (e.g.: http://developer.mbed.org/users/mbed_official/code/mbed-src/file/12a9a5f8fea0/targets/cmsis/TARGET_NORDIC/TARGET_MCU_NRF51822/nrf51.h)
takafuminaka 0:371bcac81ea2 13 -- see "nRF51 Series Reference Manual" chapter on Real Time Counter (chapter 19 in V3.0)
takafuminaka 0:371bcac81ea2 14 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,
takafuminaka 0:371bcac81ea2 15 so you can read, but don't write!
takafuminaka 0:371bcac81ea2 16
takafuminaka 0:371bcac81ea2 17 */
takafuminaka 0:371bcac81ea2 18
takafuminaka 0:371bcac81ea2 19 #include "mbed.h"
takafuminaka 0:371bcac81ea2 20 #include "nrf51_rtc.h"
takafuminaka 0:371bcac81ea2 21 #include "AS3935_ext.h"
takafuminaka 0:371bcac81ea2 22
takafuminaka 0:371bcac81ea2 23 AS3935_ext Lightning(I2C_SDA0,I2C_SCL0,0x00,P0_23);
takafuminaka 0:371bcac81ea2 24 InterruptIn IntLightning(P0_23); //IRQ AS3935
takafuminaka 0:371bcac81ea2 25
takafuminaka 0:371bcac81ea2 26 // used for the example only, not required for rtc use
takafuminaka 0:371bcac81ea2 27 DigitalOut rtc_update_led(LED1); // toggle when update_rtc is called
takafuminaka 0:371bcac81ea2 28 DigitalOut button_push_led(LED2); // toggle when button1 is pushed
takafuminaka 0:371bcac81ea2 29 DigitalIn button1(BUTTON1); // used to trigger the time report
takafuminaka 0:371bcac81ea2 30 InterruptIn button1Press(BUTTON1);
takafuminaka 0:371bcac81ea2 31 Serial pc(USBTX,USBRX);
takafuminaka 0:371bcac81ea2 32
takafuminaka 0:371bcac81ea2 33
takafuminaka 0:371bcac81ea2 34 time_t example_time() {
takafuminaka 0:371bcac81ea2 35 // set an intial time
takafuminaka 0:371bcac81ea2 36 // ...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)
takafuminaka 0:371bcac81ea2 37 time_t rawtime=0;
takafuminaka 0:371bcac81ea2 38
takafuminaka 0:371bcac81ea2 39 struct tm * init_timeinfo;
takafuminaka 0:371bcac81ea2 40
takafuminaka 0:371bcac81ea2 41 // initialize time
takafuminaka 0:371bcac81ea2 42 init_timeinfo = localtime(&rawtime); // note: must initialize the struct with this before trying to set components
takafuminaka 0:371bcac81ea2 43 // ...else code goes into the weeds!!
takafuminaka 0:371bcac81ea2 44 init_timeinfo->tm_sec = 0;
takafuminaka 0:371bcac81ea2 45 init_timeinfo->tm_min = 0;
takafuminaka 0:371bcac81ea2 46 init_timeinfo->tm_hour = 0;
takafuminaka 0:371bcac81ea2 47 init_timeinfo->tm_mon = 0;
takafuminaka 0:371bcac81ea2 48 init_timeinfo->tm_mday = 1;
takafuminaka 0:371bcac81ea2 49 init_timeinfo->tm_year = 0;
takafuminaka 0:371bcac81ea2 50
takafuminaka 0:371bcac81ea2 51 char date[24];
takafuminaka 0:371bcac81ea2 52 strftime(date,sizeof(date),"%H:%M:%S on %m/%d/%G",init_timeinfo);
takafuminaka 0:371bcac81ea2 53 pc.printf("Initial time set is %s.\r\n",date);
takafuminaka 0:371bcac81ea2 54
takafuminaka 0:371bcac81ea2 55 // compute the proper value for time in time_t type
takafuminaka 0:371bcac81ea2 56 rawtime = mktime(init_timeinfo);
takafuminaka 0:371bcac81ea2 57 return rawtime;
takafuminaka 0:371bcac81ea2 58 }
takafuminaka 0:371bcac81ea2 59 void print_time() {
takafuminaka 0:371bcac81ea2 60 // called when a button is pushed, this prints the current time to the USB-connected console
takafuminaka 0:371bcac81ea2 61 button_push_led = !button_push_led;
takafuminaka 0:371bcac81ea2 62
takafuminaka 0:371bcac81ea2 63 time_t rawtime=rtc.time();
takafuminaka 0:371bcac81ea2 64
takafuminaka 0:371bcac81ea2 65 // massage the time into a human-friendly format for printing
takafuminaka 0:371bcac81ea2 66 struct tm * timeinfo;
takafuminaka 0:371bcac81ea2 67 timeinfo = localtime(&rawtime);
takafuminaka 0:371bcac81ea2 68 char date[24];
takafuminaka 0:371bcac81ea2 69 strftime(date,sizeof(date),"%H:%M:%S on %m/%d/%G",timeinfo);
takafuminaka 0:371bcac81ea2 70 pc.printf("The current time is %s.(%d)\r\n",date,rawtime);
takafuminaka 0:371bcac81ea2 71 }
takafuminaka 0:371bcac81ea2 72
takafuminaka 0:371bcac81ea2 73 // (probably) required for rtc use
takafuminaka 0:371bcac81ea2 74 void update_rtc() {
takafuminaka 0:371bcac81ea2 75 // for use as interrupt routine, to insure that RTC is updated periodically
takafuminaka 0:371bcac81ea2 76 // ...if rtc is not read before the underlying counter rolls over (typically 512 seconds), the RTC value will be wrong
takafuminaka 0:371bcac81ea2 77 // ...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)
takafuminaka 0:371bcac81ea2 78 rtc.time();
takafuminaka 0:371bcac81ea2 79 rtc_update_led = !rtc_update_led;
takafuminaka 0:371bcac81ea2 80 // print_time();
takafuminaka 0:371bcac81ea2 81 }
takafuminaka 0:371bcac81ea2 82
takafuminaka 0:371bcac81ea2 83 void DetectLightning()
takafuminaka 0:371bcac81ea2 84 {
takafuminaka 0:371bcac81ea2 85 char OriginInt;
takafuminaka 0:371bcac81ea2 86 time_t rawtime=rtc.time();
takafuminaka 0:371bcac81ea2 87 struct tm * timeinfo;
takafuminaka 0:371bcac81ea2 88 timeinfo = localtime(&rawtime);
takafuminaka 0:371bcac81ea2 89 char date[24];
takafuminaka 0:371bcac81ea2 90 int distance;
takafuminaka 0:371bcac81ea2 91
takafuminaka 0:371bcac81ea2 92 strftime(date,sizeof(date),"%H:%M:%S on %m/%d/%G",timeinfo);
takafuminaka 0:371bcac81ea2 93
takafuminaka 0:371bcac81ea2 94 wait_ms(2); //on attend 2ms préconisation constructeur
takafuminaka 0:371bcac81ea2 95 OriginInt = Lightning.interruptSource();
takafuminaka 0:371bcac81ea2 96 distance = Lightning.lightningDistanceKm();
takafuminaka 0:371bcac81ea2 97
takafuminaka 0:371bcac81ea2 98 if (OriginInt == 1) {
takafuminaka 0:371bcac81ea2 99 pc.printf("%24s : Noise level too high. %d km\r\n",date,distance);
takafuminaka 0:371bcac81ea2 100 }
takafuminaka 0:371bcac81ea2 101 if (OriginInt == 4) {
takafuminaka 0:371bcac81ea2 102 pc.printf("%24s : Disturber detected. %d km\r\n",date,distance);
takafuminaka 0:371bcac81ea2 103 }
takafuminaka 0:371bcac81ea2 104 if (OriginInt == 8) {
takafuminaka 0:371bcac81ea2 105 distance = Lightning.lightningDistanceKm();
takafuminaka 0:371bcac81ea2 106 pc.printf("%24s : Lightning interrupt %d km\r\n",date,distance);
takafuminaka 0:371bcac81ea2 107 }
takafuminaka 0:371bcac81ea2 108 }
takafuminaka 0:371bcac81ea2 109
takafuminaka 0:371bcac81ea2 110
takafuminaka 0:371bcac81ea2 111 int main(void)
takafuminaka 0:371bcac81ea2 112 {
takafuminaka 0:371bcac81ea2 113 rtc_update_led=0;
takafuminaka 0:371bcac81ea2 114 button_push_led=0;
takafuminaka 0:371bcac81ea2 115 int hz=0;
takafuminaka 0:371bcac81ea2 116
takafuminaka 0:371bcac81ea2 117 //initialisations
takafuminaka 0:371bcac81ea2 118 pc.printf("reset\r\n");
takafuminaka 0:371bcac81ea2 119 Lightning.reset();
takafuminaka 0:371bcac81ea2 120 pc.printf("setTuneCap as 5\r\n");
takafuminaka 0:371bcac81ea2 121 Lightning.setTuneCap(5); // Tuning Parameter
takafuminaka 0:371bcac81ea2 122 pc.printf("powerup\r\n");
takafuminaka 0:371bcac81ea2 123 Lightning.powerUp();
takafuminaka 0:371bcac81ea2 124 pc.printf("setIndoors\r\n");
takafuminaka 0:371bcac81ea2 125 Lightning.setIndoors(); // Set Device into Indoor mode
takafuminaka 0:371bcac81ea2 126
takafuminaka 0:371bcac81ea2 127 pc.printf("Auto Calibration Start\r\n");
takafuminaka 0:371bcac81ea2 128 float minerr = 100;
takafuminaka 0:371bcac81ea2 129 int fincap = 7;
takafuminaka 0:371bcac81ea2 130 for(int i=0;i<16;i++) {
takafuminaka 0:371bcac81ea2 131 Lightning.setTuneCap(i); // Tuning Parameter
takafuminaka 0:371bcac81ea2 132 hz = Lightning.MeasureLCOFreq();
takafuminaka 0:371bcac81ea2 133 float err = (hz-500000.)/500000.*100.;
takafuminaka 0:371bcac81ea2 134 pc.printf("%d : hz=%10d Hz (%5.2f%%)\r\n",i,hz,err);
takafuminaka 0:371bcac81ea2 135 if ( abs(err) < minerr ) {
takafuminaka 0:371bcac81ea2 136 minerr = abs(err);
takafuminaka 0:371bcac81ea2 137 fincap = i;
takafuminaka 0:371bcac81ea2 138 }
takafuminaka 0:371bcac81ea2 139 }
takafuminaka 0:371bcac81ea2 140 Lightning.setTuneCap(fincap); // Tuning Parameter
takafuminaka 0:371bcac81ea2 141 wait_ms(100);
takafuminaka 0:371bcac81ea2 142 hz = Lightning.MeasureLCOFreq();
takafuminaka 0:371bcac81ea2 143 float err = (hz-500000.)/500000.*100.;
takafuminaka 0:371bcac81ea2 144 pc.printf("Final %d : hz=%10d Hz (%5.2f%%)\r\n",fincap,hz,err);
takafuminaka 0:371bcac81ea2 145
takafuminaka 0:371bcac81ea2 146 pc.printf("Auto Calibration finished\r\n");
takafuminaka 0:371bcac81ea2 147
takafuminaka 0:371bcac81ea2 148 // user selectable, any time < 512 seconds is OK
takafuminaka 0:371bcac81ea2 149 #define PERIODIC_UPDATE 1
takafuminaka 0:371bcac81ea2 150 Ticker rtc_ticker;
takafuminaka 0:371bcac81ea2 151 rtc_ticker.attach(&update_rtc, PERIODIC_UPDATE); // update the time regularly
takafuminaka 0:371bcac81ea2 152
takafuminaka 0:371bcac81ea2 153 time_t initial_time = example_time();
takafuminaka 0:371bcac81ea2 154 rtc.set_time(initial_time);
takafuminaka 0:371bcac81ea2 155
takafuminaka 0:371bcac81ea2 156 button1Press.fall(&print_time); // when button1 is pressed, this calls rtc.time() and prints it
takafuminaka 0:371bcac81ea2 157
takafuminaka 0:371bcac81ea2 158 // Lightning.setIndoors(); // Set Device into Indoor mode
takafuminaka 0:371bcac81ea2 159 Lightning.setOutdoors(); // Set Device into Outdoor mode
takafuminaka 0:371bcac81ea2 160 IntLightning.rise(&DetectLightning);
takafuminaka 0:371bcac81ea2 161
takafuminaka 0:371bcac81ea2 162 while (true) {
takafuminaka 0:371bcac81ea2 163 sleep();
takafuminaka 0:371bcac81ea2 164 }
takafuminaka 0:371bcac81ea2 165 }