Ag demo with soil moisture

Dependencies:   DOGS102 ISL29011 MMA845x MPL3115A2 NCP5623B libmDot mbed-rtos mbed-src

Fork of MTDOT-EVBDemo-DRH by Dave Heitzman

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