Prelude
In my last post here ([Firecracker Analyzer] Creating a Wireless Sensor Node using TI's stuff.) I built up a wireless sensor node using the Anaren Air Booster Pack. They are cheap and I think I will be using these quite a lot in future projects. I wanted to use my solar harvester to power the FR5969 board but have run into issues with the boards I made and don't have any more BQ25504s to experiment with hence it has come to a halt. Instead I am now using the Fuel Booster Pack with some minor surgery to be charged by solar panels. In this post I have two things to explain.
1. To finish the code on the Wireless Node for the FR5969 and give it to you for further modification
2. Modifying the Fuel Booster Pack for Solar Power
Lets get started
Making the Wireless Node
Recap
I have the two launchpads setup as follows:
1. Wireless Node with the FR5969 Launchpad and Fuel Booster Pack and the Air Booster Pack
2. Station Node with the F5529LP with the Air Booster Pack
Lets start with some code.
Wireless Base Station Code
The base station code is the same as from the Energia Examples. For Demo purposes, the serial stream is connected to the USB emulated port and ot the PC. I will make one modification that will allow me to send this data to the Pins on the Board itself and then I will connect this to the Beagle Bone Black which is my gateway. The code is as follows:
/** * ---------------------------------------------------------------------------- * WirelessMonitorHub.ino - wireless monitor hub sketch using AIR430Boost ETSI driver. * Copyright (C) 2012-2013 Anaren Microwave, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * This example demonstrates usage of the AIR430BoostETSI library which uses * the 430Boost-CC110L AIR Module BoosterPack created by Anaren Microwave, Inc. * and available through the TI eStore, for the European Union. * * ---------------------------------------------------------------------------- * * Note: This file is part of AIR430Boost. * * ---------------------------------------------------------------------------- * * Description * =========== * * Acts as a simple receiver for a star network. The hub node can receive both * broadcast messages and messages directed to its assigned address. The hub * node should not be assigned to address 0 (broadcast address). To create an * additional network, simply change the hub address. * * ---------------------------------------------------------------------------- * * This example assumes that two BoosterPacks will be used to showcase the * wireless radio communication functionality. This same code should be * programmed to both LaunchPad development kits. * * This BoosterPack relies on the SPI hardware peripheral and two additional * GPIO lines for SPI chip-select and GDO0 for packet handling. They use pins 18 * and 19 respectively. * * In the default configuration, this BoosterPack is not compatible with an * external crystal oscillator. This can be changed, if necessary, and would * require reconfiguration of the BoosterPack hardware and changes to the * AIR430BoostETSI library. Refer to the BoosterPack User's Manual if necessary. * * ETSI regulations must be followed when using this library. This example * limits the wireless duty cycle to 0.1% per ETSI. * * For complete information, please refer to the BoosterPack User's Manual * available at: * https://www.anaren.com/air/cc110l-air-module-boosterpack-embedded-antenna-module-anaren * * To purchase the 430Boost-CC110L AIR module BoosterPack kit, please visit the * TI eStore at: * https://estore.ti.com/430BOOST-CC110L-CC110L-RF-Module-BoosterPack-P2734.aspx */ /** * The AIR430BoostETSI library uses the SPI library internally. Energia does not * copy the library to the output folder unless it is referenced here. The order * of includes is also important due to this fact. */ #include <SPI.h> #include <AIR430BoostETSI.h> // ----------------------------------------------------------------------------- /** * Defines, enumerations, and structure definitions */ #define ADDRESS_LOCAL 0x01 /** * sPacket - packet format. */ struct sPacket { uint8_t from; // Local node address that message originated from uint8_t message[59]; // Local node message [MAX. 59 bytes] }; // ----------------------------------------------------------------------------- /** * Global data */ struct sPacket rxPacket; // ----------------------------------------------------------------------------- // Main example void setup() { // The radio library uses the SPI library internally, this call initializes // SPI/CSn and GDO0 lines. Also setup initial address, channel, and TX power. Radio.begin(ADDRESS_LOCAL, CHANNEL_1, POWER_MAX); rxPacket.from = 0; memset(rxPacket.message, 0, sizeof(rxPacket.message)); // Setup serial for debug printing. Serial.begin(9600); /** * Setup LED for example demonstration purposes. * * Note: Set radio first to ensure that GDO2 line isn't being driven by the * MCU as it is an output from the radio. */ pinMode(RED_LED, OUTPUT); // Use red LED to display message reception digitalWrite(RED_LED, LOW); } void loop() { // Turn on the receiver and listen for incoming data. Timeout after 1 seconds. // The receiverOn() method returns the number of bytes copied to rxData. if (Radio.receiverOn((unsigned char*)&rxPacket, sizeof(rxPacket), 1000) > 0) { digitalWrite(RED_LED, HIGH); Serial.print("FROM: "); Serial.print(rxPacket.from); Serial.print(" MSG: "); Serial.println((char*)rxPacket.message); digitalWrite(RED_LED, LOW); } // Note: This sketch never transmits so no additional delay required to meet ETSI // requirements. }
In the above code, instead of Serial, we will use Serial1 which will cause the data to be sent over USART1 which is the Pins on the LP. Thats it! The LED will blink every-time data is received allowing us to debug.
Wireless Node
The code for the wireless node is also very simple, but is a bit tricky since the FR5969 shares PINs when it comes to the I2C and SPI. My problem is that I have the sensors and Fuel Booster Pack talking over the I2C and the CC110L talking over the SPI bus which causes a conflict. The solution is to have a soft I2C which I can just bit bang. I got a library from the 430oh forums but faced some issues with it. The second problem is that the Fuel Booster Pack has the I2C pins on the wrong side hence I need to do a little modificaion as follows.
Fuel Tank Modification
Below are some images of the modifications I made to the Fuel Tank.
As you can see, the I2C lines traces are cut on the PCB and then wires are used to reconnect them to the appropriate pins. Additionally I soldered some wires for the Solar Panel from the GND and Charge In test points. Simple.
Node Code
Before I give you the code, I will explain a few things about it. The base code is the same as the demo code from energia. I added a soft Serial Library but faced some problems while using it. I also added some code to add my data to the packet which will be sent across.
One major change here is that I have a sleep function that allows me to take the FR5969 into LPM3 which means the timer is active and everything else is shutdown. The function was taken from the forums as well and modified a bit to work with the FR5969
Here is the code.
/* * Description: This file is part of the Air Quality Sensor Project. Parts of the * code have been forked from the Demo code for the ANaren Booster Packs. * * -- * Copyright (C) 2014 Inderpreet Singh(er.inderpreet@gmail.com), Thought Process Designs * Web : http://google.com/+InderpreetSingh * http://embeddedcode.wordpress.com * * This software may be distributed and modified under the terms of the GNU * General Public License version 2 (GPL2) as published by the Free Software * Foundation and appearing in the file LICENSE.TXT included in the packaging of * this file. Please note that GPL2 Section 2[b] requires that all works based * on this software must also be made publicly available under the terms of * the GPL2 ("Copyleft"). * * We put a lot of time and effort into our project and hence this copyright * notice ensures that people contribute as well as each contribution is * acknowledged. Please retain this original notice and if you make changes * please document them below along with your details. * * The latest copy of this project/library can be found at: * https://github.com/inderpreet/ * */ // ---------------------------------------------------------------------------- #include <SPI.h> #include <AIR430BoostETSI.h> #include <I2C_SoftwareLibrary.h> #define SCL_PIN P3_5 #define SDA_PIN P3_6 // ----------------------------------------------------------------------------- /** * Defines, enumerations, and structure definitions */ #define ADDRESS_LOCAL 0x02 #define ADDRESS_REMOTE 0x01 /** * sPacket - packet format. */ struct sPacket { uint8_t from; // Local node address that message originated from uint8_t message[59]; // Local node message [MAX. 59 bytes] }; volatile unsigned long delaycounter; void StartTimer() { //To use the VLO, Use the following: //BCSCTL &= ~DIVA_3; // ACLK without divider - nominally 12kHz //BCSCTL3 = (LFXT1S_2); // Source ACLK from VLO TA1CCTL0 = CCIE; // CCR0 interupt activated TA1CCR0=11999; // 12000 ticks is nominally 1 second TA1CTL = TASSEL_1 | ID_0 | MC_1; // Clock for TIMER = ACLK, No division, up mode //Alternatively to use the Crystal for more accuracy use the Following /* P2SEL |= (BIT6 | BIT7); // Reset P2_6 & P2_7 BCSCTL1 &= ~DIVA_3; // ACLK without divider - 32768kHz BCSCTL3 = (LFXT1S_0 | XCAP_3);// Source ACLK from XTal TA1CCTL0 = CCIE; // CCR0 interupt activated TA1CCR0=4096-1; // we are dividing clock by 8, so 4096 ticks = 1 second TA1CTL = TASSEL_1 | ID_3 | MC_1; // Clock for TIMER = ACLK, By 8 division, up mode */ } void StopTimer() { TA1CTL|=TACLR; } //Set Up the Interrupt routine... __attribute__((interrupt(TIMER1_A0_VECTOR))) void timer_isr (void) { ++delaycounter; //increment our seconds counter __bic_status_register_on_exit(LPM3_bits); //exit at full power. } //And here is our delay function... //this will create delays of up to approx 136 years //with 1 second resolution. void longdelay(unsigned long delayseconds) { delaycounter=0; StartTimer(); //start our timer up while (delaycounter<delayseconds) //while we haven't reached our count... __bis_status_register(LPM3_bits+GIE); //switch back to LPM3. StopTimer(); //times up, stop our timers. }; // ----------------------------------------------------------------------------- /** * Global data */ struct sPacket txPacket; SoftwareWire Wire(SDA_PIN, SCL_PIN); void confHDC1000(void){ Wire.beginTransmission(0x43); Wire.write(byte(0x02)); Wire.write(byte(0x1e)); Wire.write(byte(0x00)); Wire.endTransmission(true); } void readTemp(void){ Wire.beginTransmission(0x43); Wire.write(byte(0x00)); Wire.endTransmission(false); delay(500); Wire.requestFrom(0x43, 4); while(Wire.available()){ char c=Wire.read(); Serial.print(c, HEX); } } // ----------------------------------------------------------------------------- // Main App Code void setup() { // The radio library uses the SPI library internally, this call initializes // SPI/CSn and GDO0 lines. Also setup initial address, channel, and TX power. Radio.begin(ADDRESS_LOCAL, CHANNEL_1, POWER_MAX); txPacket.from = ADDRESS_LOCAL; memset(txPacket.message, 0, sizeof(txPacket.message)); // Setup serial for debug printing. Serial.begin(9600); /** * Setup LED for example demonstration purposes. * * Note: Set radio first to ensure that GDO2 line isn't being driven by the * MCU as it is an output from the radio. */ pinMode(RED_LED, OUTPUT); // Use red LED to display message reception digitalWrite(RED_LED, LOW); Wire.begin(); confHDC1000(); } void loop() { int i; int temperature, humidity, dust; //readTemp(); temperature=17; humidity=23; dust=25; digitalWrite(RED_LED, HIGH); // Carpet bom with zeros for (i = 0; i <= 0x2A; i++) { txPacket.message[i] = 0x00; } // Fill In packet Data Here /* TO-DO Need to get sensor data and fill it here */ sprintf((char*)txPacket.message, ":T%dCH%d\%D%d#", temperature, humidity, dust); // Transmit Data Here Radio.transmit(ADDRESS_REMOTE, (unsigned char*)&txPacket, sizeof(txPacket)); digitalWrite(RED_LED, LOW); longdelay(10); }
The node will essentially read sensors, create a packet, send the data and go to sleep. The original author says we can make it sleep for a LONG time so feel free to experiment with it and let me know how that goes. The library is attached at the bottom.
ScreenShot
Here is the screenshot of the console. Not very interesting but this is what is received by the base station...
It can be seen that temperature, humidity and dust values arrive in ascii format. This is useful for debugging and we can use javascript to extract what we want easily. Our gateway is running NodeJS as shown in my blog post
[Firecracker Analyzer] Obligatory Guide - Using Sierra Air Vantage with your Device
and we will use some JS to do the rest.
At this point, our Node and Base station is ready. I don't have the sensors but its a simple matter of either I2C reading or analog reading which can be done according to the sensor selected
I hope this helps anyone wanted to make a wireless sensor node in the future. In my next post, I will connect it the the BBB vs JS and then allow the data to be sent to Sierra wireless.
Cheers
IP