Ag demo with soil moisture
Dependencies: DOGS102 ISL29011 MMA845x MPL3115A2 NCP5623B libmDot mbed-rtos mbed-src
Fork of MTDOT-EVBDemo-DRH by
Diff: main.cpp
- Revision:
- 0:bdd16076aaa5
- Child:
- 1:ac9595d0f0e7
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Mon Jul 06 19:58:08 2015 +0000 @@ -0,0 +1,504 @@ +/** + * @file main.cpp + * @brief Main application for mDot-EVB demo + * @author Tim Barr MultiTech Systems Inc. + * @version 1.0 + * @see + * + * Copyright (c) 2015 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mbed.h" +#include "MMA845x.h" +#include "MPL3115A2.h" +#include "ISL29011.h" +#include "NCP5623B.h" +#include "DOGS102.h" +#include "font_6x8.h" +#include "MultiTech_Logo.h" +#include "mDot.h" +#include "rtos.h" +#include <string> +#include <vector> + +enum LED1_COLOR { + RED = 0, + GREEN = 1 +}; + +/* + * union for converting from 32-bit to 4 8-bit values + */ +union convert32 { + int32_t f_s; // convert from signed 32 bit int + uint32_t f_u; // convert from unsigned 32 bit int + uint8_t t_u[4]; // convert to 8 bit unsigned array +}; + +/* + * union for converting from 16- bit to 2 8-bit values + */ +union convert16 { + int16_t f_s; // convert from signed 16 bit int + uint16_t f_u; // convert from unsigned 16 bit int + uint8_t t_u[2]; // convert to 8 bit unsigned array +}; + +//DigitalIn mDot02(PA_2); // GPIO/UART_TX +//DigitalOut mDot03(PA_3); // GPIO/UART_RX +//DigitalIn mDot04(PA_6); // GPIO/SPI_MISO +//DigitalIn mDot06(PA_8); // GPIO/I2C_SCL +//DigitalIn mDot07(PC_9); // GPIO/I2C_SDA + +InterruptIn mDot08(PA_12); // GPIO/USB PB S1 on EVB +InterruptIn mDot09(PA_11); // GPIO/USB PB S2 on EVB + +//DigitalIn mDot11(PA_7); // GPIO/SPI_MOSI + +InterruptIn mDot12(PA_0); // GPIO/UART_CTS PRESSURE_INT2 on EVB +DigitalOut mDot13(PC_13,1); // GPIO LCD_C/D +InterruptIn mDot15(PC_1); // GPIO LIGHT_PROX_INT on EVB +InterruptIn mDot16(PA_1); // GPIO/UART_RTS ACCEL_INT2 on EVB +DigitalOut mDot17(PA_4,1); // GPIO/SPI_NCS LCD_CS on EVB + +//DigitalIn mDot18(PA_5); // GPIO/SPI_SCK + +//DigitalInOut mDot19(PB_0,PIN_INPUT,PullNone,0); // GPIO PushPull LED Low=Red High=Green set MODE=INPUT to turn off +AnalogIn mDot20(PB_1); // GPIO Current Sense Analog in on EVB + +Serial debugUART(PA_9, PA_10); // mDot debug UART + +//Serial mDotUART(PA_2, PA_3); // mDot external UART mDot02 and mDot03 + +I2C mDoti2c(PC_9,PA_8); // mDot External I2C mDot6 and mDot7 + +SPI mDotspi(PA_7,PA_6,PA_5); // mDot external SPI mDot11, mDot4, and mDot18 + +// replace these values with the proper network settings +static std::string config_network_name = "TAB-CubeNet"; +static std::string config_network_pass = "1nt3gral"; +static uint8_t config_frequency_sub_band = 5; + +uint8_t result, pckt_time=10; +char data; +unsigned char test; +char txtstr[17]; +int32_t num_whole, mdot_ret; +uint32_t pressure; +int16_t num_frac; + +bool exit_program = false; + +MMA845x_DATA accel_data; +MPL3115A2_DATA baro_data; +uint16_t lux_data; +MMA845x* evbAccel; +MPL3115A2* evbBaro; +ISL29011* evbAmbLight; +NCP5623B* evbBackLight; +DOGS102* evbLCD; +mDot* mdot_radio; + +convert32 convertl; +convert16 converts; + +void pb1ISR(void); +void pb2ISR(void); + +void log_error(mDot* dot, const char* msg, int32_t retval); + +void config_pkt_xmit (void const *args); + +Thread* thread1; + +int main() +{ + + std::vector<uint8_t> mdot_data; + std::vector<uint8_t> mdot_EUI; + uint16_t i = 0; + + debugUART.baud(921600); +// mDotUART.baud(9600); // mdot UART unused but available on external connector + + thread1 = new Thread(config_pkt_xmit); + evbAccel = new MMA845x(mDoti2c,MMA845x::SA0_VSS); // setup Accelerometer + evbBaro = new MPL3115A2(mDoti2c); // setup Barometric sensor + evbAmbLight = new ISL29011(mDoti2c, NULL); // Setup Ambient Light Sensor + evbBackLight = new NCP5623B(mDoti2c); // setup backlight and LED 2 driver chip + evbLCD = new DOGS102(mDotspi, mDot17, mDot13); // setup LCD + + printf("\n\r setup mdot\n\r"); + + // get a mDot handle + mdot_radio = mDot::getInstance(); + + if (mdot_radio) { + // reset to default config so we know what state we're in + mdot_radio->resetConfig(); + + // Setting up LED1 as activity LED + mdot_radio->setActivityLedPin(PB_0); + mdot_radio->setActivityLedEnable(true); + + // Read node ID + mdot_EUI = mdot_radio->getDeviceId(); + printf("mDot EUI = "); + + for (i=0; i<mdot_EUI.size(); i++) { + printf("%02x ", mdot_EUI[i]); + } + printf("\n\r"); + + +// set up the mDot with our network information + printf("setting frequency sub band\r\n"); + if ((mdot_ret = mdot_radio->setFrequencySubBand(config_frequency_sub_band)) != mDot::MDOT_OK) { + log_error(mdot_radio, "failed to set frequency sub band", mdot_ret); + } + + printf("setting network name\r\n"); + if ((mdot_ret = mdot_radio->setNetworkName(config_network_name)) != mDot::MDOT_OK) { + log_error(mdot_radio, "failed to set network name", mdot_ret); + } + + printf("setting network password\r\n"); + if ((mdot_ret = mdot_radio->setNetworkPassphrase(config_network_pass)) != mDot::MDOT_OK) { + log_error(mdot_radio, "failed to set network password", mdot_ret); + } + + // attempt to join the network + printf("joining network\r\n"); + while ((mdot_ret = mdot_radio->joinNetwork()) != mDot::MDOT_OK) { + log_error(mdot_radio,"failed to join network:", mdot_ret); + if (mdot_radio->getFrequencyBand() == mDot::FB_868){ + mdot_ret = mdot_radio->getNextTxMs(); + } + else { + mdot_ret = 0; + } + + printf("delay = %lu\n\r",mdot_ret); + osDelay(mdot_ret + 1); + } + } else { + printf("radio setup failed\n\r"); + //exit(1); + } + + osDelay(200); + evbBackLight->setPWM(NCP5623B::LED_3,16); // enable LED2 on EVB and set to 50% PWM + + /* + * Setup SW1 as program stop function + */ + mDot08.disable_irq(); + mDot08.fall(&pb1ISR); + + /* + * need to call this function after rise or fall because rise/fall sets + * mode to PullNone + */ + mDot08.mode(PullUp); + mDot08.enable_irq(); + + /* + * Setup SW2 as packet time change + */ + mDot09.disable_irq(); + mDot09.fall(&pb2ISR); + + /* + * need to call this function after rise or fall because rise/fall sets + * mode to PullNone + */ + mDot09.mode(PullUp); + mDot09.enable_irq(); + + /* + * Setting other InterruptIn pins with Pull Ups + */ + mDot12.mode(PullUp); + mDot15.mode(PullUp); + mDot16.mode(PullUp); + + + // sets LED2 to ramp up to 50% max current at 32 mS per step + evbBackLight->setLEDCurrent(16); + + printf("font table address %p\n\r",&font_6x8); + printf("bitmap address %p\n\r",&MultiTech_Logo); + + printf("Start of Test\n\r"); + + evbLCD->startUpdate(); + evbLCD->writeBitmap(0,0,MultiTech_Logo); + + sprintf(txtstr,"MTDOT"); + evbLCD->writeText(24,3,font_6x8,txtstr,strlen(txtstr)); + sprintf(txtstr,"Evaluation"); + evbLCD->writeText(24,4,font_6x8,txtstr,strlen(txtstr)); + sprintf(txtstr,"Board"); + evbLCD->writeText(24,5,font_6x8,txtstr,strlen(txtstr)); + + osDelay (500); // allows other threads to process + printf("shutdown LEDs and update LCD:\n\r"); + evbBackLight->shutdown(); + evbLCD->endUpdate(); + + osDelay (1000); // allows other threads to process + printf("Turn on LED2\n\r"); + evbBackLight->setLEDCurrent(16); + + data = evbAccel->getWhoAmI(); + printf("Accelerometer who_am_i value = %x \n\r", data); + + result = evbAccel->getStatus(); + printf("status byte = %x \n\r", result); + + printf("Barometer who_am_i check = %s \n\r", evbBaro->testWhoAmI() ? "TRUE" : "FALSE"); + + result = evbBaro->getStatus(); + printf("status byte = %x \n\r", result); + + /* + * Setup the Accelerometer for 8g range, 14 bit resolution, Noise reduction off, sample rate 1.56 Hz + * normal oversample mode, High pass filter off + */ + evbAccel->setCommonParameters(MMA845x::RANGE_8g,MMA845x::RES_MAX,MMA845x::LN_OFF, + MMA845x::DR_1_56,MMA845x::OS_NORMAL,MMA845x::HPF_OFF ); + + /* + * Setup the Barometric sensor for post processed Ambient pressure, 4 samples per data acquisition. + * and a sample taken every second when in active mode + */ + evbBaro->setParameters(MPL3115A2::DATA_NORMAL, MPL3115A2::DM_BAROMETER, MPL3115A2::OR_16, + MPL3115A2::AT_1); + /* + * Setup the Ambient Light Sensor for continuous Ambient Light Sensing, 16 bit resolution, + * and 16000 lux range + */ + + evbAmbLight->setMode(ISL29011::ALS_CONT); + evbAmbLight->setResolution(ISL29011::ADC_16BIT); + evbAmbLight->setRange(ISL29011::RNG_16000); + + /* + * Set the accelerometer for active mode + */ + evbAccel->activeMode(); + + /* + * Clear the min-max registers in the Barometric Sensor + */ + evbBaro->clearMinMaxRegs(); + + evbBackLight->setLEDCurrent(0); + + /* + * Main data acquisition loop + */ + pckt_time = 10; + i = 0; + + do { + evbLCD->startUpdate(); + evbLCD->clearBuffer(); + + /* + * Test Accelerometer XYZ data ready bit to see if acquisition complete + */ + do { + osDelay(100); // allows other threads to process + result = evbAccel->getStatus(); + } while ((result & MMA845x::XYZDR) == 0 ); + + /* + * Retrieve and print out accelerometer data + */ + accel_data = evbAccel->getXYZ(); + + sprintf(txtstr,"Accelerometer"); + evbLCD->writeText(0,0,font_6x8,txtstr,strlen(txtstr)); + sprintf(txtstr, "x = %d", accel_data._x); + evbLCD->writeText(20,1,font_6x8,txtstr,strlen(txtstr)); + sprintf(txtstr, "y = %d", accel_data._y); + evbLCD->writeText(20,2,font_6x8,txtstr,strlen(txtstr)); + sprintf(txtstr, "z = %d", accel_data._z ); + evbLCD->writeText(20,3,font_6x8,txtstr,strlen(txtstr)); + + /* + * Trigger a Pressure reading + */ + evbBaro->setParameters(MPL3115A2::DATA_NORMAL, MPL3115A2::DM_BAROMETER, MPL3115A2::OR_16, + MPL3115A2::AT_1); + evbBaro->triggerOneShot(); + + /* + * Test barometer device status to see if acquisition is complete + */ + do { + osDelay(100); // allows other threads to process + result = evbBaro->getStatus(); + } while ((result & MPL3115A2::PTDR) == 0 ); + + /* + * Retrieve and print out barometric pressure + */ + pressure = evbBaro->getBaroData() >> 12; // convert 32 bit signed to 20 bit unsigned value + num_whole = pressure >> 2; // 18 bit integer significant + num_frac = (pressure & 0x3) * 25; // 2 bit fractional 0.25 per bit + sprintf(txtstr,"Press=%ld.%02d Pa", num_whole, num_frac); + evbLCD->writeText(0,4,font_6x8,txtstr,strlen(txtstr)); + + /* + * Trigger a Altitude reading + */ + evbBaro->setParameters(MPL3115A2::DATA_NORMAL, MPL3115A2::DM_ALTIMETER, MPL3115A2::OR_16, + MPL3115A2::AT_1); + evbBaro->triggerOneShot(); + + /* + * Test barometer device status to see if acquisition is complete + */ + do { + osDelay(100); // allows other threads to process + result = evbBaro->getStatus(); + } while ((result & MPL3115A2::PTDR) == 0 ); + + /* + * Retrieve and print out altitude and temperature + */ + baro_data = evbBaro->getAllData(false); + baro_data._baro /= 4096; // convert 32 bit signed to 20 bit signed value + num_whole = baro_data._baro / 16; // 18 bit signed significant integer + num_frac = (baro_data._baro & 0xF) * 625 / 100; // 4 bit fractional .0625 per bit + sprintf(txtstr,"Alti=%ld.%03d m", num_whole, num_frac); + evbLCD->writeText(0,5,font_6x8,txtstr,strlen(txtstr)); + num_whole = baro_data._temp / 16; // 8 bit signed significant integer + num_frac = (baro_data._temp & 0x0F) * 625 / 100; // 4 bit fractional .0625 per bit + sprintf(txtstr,"Temp=%ld.%03d C", num_whole, num_frac); + evbLCD->writeText(0,6,font_6x8,txtstr,strlen(txtstr)); + + /* + * retrieve and print out Ambient Light level + */ + lux_data = evbAmbLight->getData(); + num_whole = lux_data * 24 / 100; // 16000 lux full scale .24 lux per bit + num_frac = lux_data * 24 % 100; + sprintf(txtstr, "Light=%ld.%02d lux", num_whole, num_frac ); + evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr)); + + evbLCD->endUpdate(); + printf("finished iteration %d\n\r",(++i)); + + if (i % pckt_time == 0) { // check packet counter will send packet every 2-5-10 data collection loops + mdot_data.clear(); + mdot_data.push_back(0x0E); // key for Current Acceleration 3-Axis Value + converts.f_s = accel_data._x *4; // shift data 2 bits while retaining sign + mdot_data.push_back(converts.t_u[1]); // get 8 MSB of 14 bit value + converts.f_s = accel_data._y * 4; // shift data 2 bits while retaining sign + mdot_data.push_back(converts.t_u[1]); // get 8 MSB of 14 bit value + converts.f_s = accel_data._z * 4; // shift data 2 bits while retaining sign + mdot_data.push_back(converts.t_u[1]); // get 8 MSB of 14 bit value + mdot_data.push_back(0x08); // key for Current Pressure Value + convertl.f_u = pressure; // pressure data is 20 bits unsigned + mdot_data.push_back(convertl.t_u[2]); + mdot_data.push_back(convertl.t_u[1]); + mdot_data.push_back(convertl.t_u[0]); + mdot_data.push_back(0x05); // key for Current Ambient Light Value + converts.f_u = lux_data; // data is 16 bits unsigned + mdot_data.push_back(converts.t_u[1]); + mdot_data.push_back(converts.t_u[0]); + mdot_data.push_back(0x0B); // key for Current Temperature Value + converts.f_s = baro_data._temp; // temperature is signed 12 bit + mdot_data.push_back(converts.t_u[1]); + mdot_data.push_back(converts.t_u[0]); + + if ((mdot_ret = mdot_radio->send(mdot_data)) != mDot::MDOT_OK) { + log_error(mdot_radio, "failed to send", mdot_ret); + } else { + printf("successfully sent data to gateway\r\n"); + } + } + } while(!exit_program | (i > 65000)); + + evbBaro->triggerOneShot(); + + do { + osDelay(200); // allows other threads to process + result = evbBaro->getStatus(); + } while ((result & MPL3115A2::PTDR) == 0 ); + + baro_data = evbBaro->getAllData(true); + printf ("minBaro=%ld maxBaro=%ld minTemp=%d maxTemp=%d\n\r", baro_data._minbaro, baro_data._maxbaro, + baro_data._mintemp, baro_data._maxtemp); + + printf("End of Test\n\r"); + +} + +/* + * Ends program when button 1 pushed + */ +void pb1ISR(void) +{ + printf("calling ISR for SW1\n\r"); + + exit_program = true; +} + +/* + * changes packet transmit time to every other, every fifth, or every tenth sample when button 2 pushed + * Also triggers a thread to transmit a configuration packet + */ +void pb2ISR(void) +{ + + printf("calling ISR for SW2\n\r"); + + if (pckt_time >= 5) + pckt_time /= 2; + else pckt_time = 20; + + thread1->signal_set(0x10); // signal config_pkt_xmit to send packet + + printf ("pckt_time = %d\n\r",pckt_time); + +} + +void log_error(mDot* dot, const char* msg, int32_t retval) +{ + printf("%s - %ld:%s, %s\r\n", msg, retval, mDot::getReturnCodeString(retval).c_str(), dot->getLastError().c_str()); +} + +void config_pkt_xmit (void const *args) +{ + + std::vector<uint8_t> data; + + while (true) { + Thread::signal_wait(0x10); // wait for pb2ISR to signal send + data.clear(); + data.push_back(0x0F); // key for Configuration data (packet transmission timer) + data.push_back(pckt_time); + + if ((mdot_ret = mdot_radio->send(data)) != mDot::MDOT_OK) { + log_error(mdot_radio, "failed to send config data", mdot_ret); + } else { + printf("sent config data to gateway\r\n"); + } + } +}