BLE Lightning sensor for Nordic NRF51822 based module
Dependencies: AS3935 AS3935_ext BLE_API mbed nRF51822 nrf51_rtc
main.cpp@0:371bcac81ea2, 2015-08-27 (annotated)
- 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?
User | Revision | Line number | New 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 | } |