Sensor Array using Particle Cloud with RedBear Duo

Sensor Array with RedBear Duo and Particle Cloud

What we want to achieve

Using a single development board to read multiple sensors attached and send data to the cloud for further processing.

Additional considerations:

  • Sensors need to be turned on before reading and off after reading is complete
  • Post-reading all sensors device go into sleep mode
  • Reduce traffic with Cloud
  • The function needs to function sensor agnostic. Read value and forward to Cloud, any processing or interpretation of values needs to be done outside 
  • Use RedBear Duo
  • Sensor Detection - for suitable sensors (reporting a predictable value when not powered or used) a sensor detection would detect if sensors are connected
About RedBear Duo

    The RedBear Duo came to life through a Kickstarter Campaign in 2015/2016. It features Wifi and BLE on a small factor as well as Particle Cloud support.

    With its integration with Particle Cloud, it allows for the development to be taking place in the Cloud (through the Particle Cloud IDE) as well as pushing updates over the air, sending commands from the WebIDE (or API) to the device.

    For Wifi it uses a built-in chip antenna and also allows to connect an external antenna for better range.

    In addition to the Particle Cloud IDE, the following platforms and languages are available: Arduino IDE, Particle CLI, JavaScript and more.

    RedBear was bought up by Particle.io recently, so we don't expect for this platform to see much development, however, we do expect a number of these devices to become available.

    A great little bear for your projects!

    Requirements

    • RedBear Duo - with firmware version 0.3.1+, connected to your Wifi
    • Up to seven sensors - we have used two moisture sensors in our proof of concept. All sensors need to report a value within a consistent threshold when not powered (to determine if they are powered on or not).
    • Breadboards and jumper wires
    • Particle IDE account

      Restrictions

      • This tip is focused on Particle IDE and RedBear Duo
      • Using a single breadboard might be a bit restrictive due to the number and type of sensors. We have used two of our expandable breadboards and connected them together.

      How to

      We connect the sensors to the RedBear Duo:

      • All sensor GND are connected back to the board GND
      • all VCC connect to individual Digital Pins 
      • all analog out from the sensors are connected to individual Digital Pins
      • The digital and analog pin numbers are matched up - e.g. for D0, use A0. The configuration of the Digital/Analog Pin couples can be configured in the code in line 56.
        Depending on the sensors used you can also tie back all sensor analog outputs to the same Analog Pin on the RedBear - just change line 56

       The code goes through the configured sensors and create a string with the sensor readings. Where it has determined there is no sensor attached, it will show 0.

      Example String: 1023,2111,0,0,0,0,0

      Once the reading is done and the string is put together it is sent to the Particle cloud as a private event. The ID of the event can be configured in line 50 - we named it "Patch0/Sensor" .. Patch0 for our first veggie patch, Sensor for sensor readings.

      Once the event is sent, it can be viewed in the Particle Cloud IDE or consumed by the API. We will follow up with a seperate tip on how to do this.

      Wiring
      This is the wiring used for the proof of concept. You might have to adapt to suit your sensors.

       Sensor 1 RedBear Duo
      GND GND
      VCC D0
      DO Not used
      AO A0

       

       Sensor 2 RedBear Duo
      GND GND
      VCC D1
      DO Not used
      AO A1

       

      Sensor Array with RedBear Duo

      Code 

      // ------------
      // Read Moisture Sensors on RedBear and send data to Particle Cloud
      //
      // Features:
      // 1) Detect number of sensors connected
      // 2) Use Sleepmode to go reduce power consumption
      //
      // Notes:
      //
      // Sensor 0 is on D0/A0, Sensor 1 is on D1/A1 and so on
      // We are not using D7 as this is used by internal LED which we are using indicator that reaading is in progress
      //
      // As the code executes quite quickly and goes straight into sleep, you might find it difficult flashing new firmware.
      // Recommend to start off with sleep commented out - you will need to hit reset button to trigger new reading.
      // Sleep is commented out by default (Line 114)
      //
      // Alternative is to wait for device to go to sleep, and flash firmware.
      // Then press and hold RESET + SETUP button, the let go of RESET until white or purple light comes back.
      //
      // 19 December 2018
      // Author: dante@serveronthemove.com.au
      // Hardware: RedBear Duo
      // Firmware: v0.3.3 - should work with earlier versions
      //
      // Sensors: 4 pin Moisture sensor with Analog output
      //
      // Wiring:
      // Moisture Sensor -> RedBear Duo
      // GND -> GND
      // VCC -> Dx
      // DO - Not used
      // AO -> Ax
      //
      // For example, using two sensors
      // Sensor 1 uses A0 and D0
      // Sensor 2 uses A4 and D4
      // The code will automatically detect the sensors, however it is important that Analog and Digital are aligned.
      // ------------

      /*
      declare variables
      */
      const int numberOfSensors = 7; // how many sensor are we be scanning
      const int settleIv = 2000; // how long to wait between turning sensor on and reading from sensor
      const int sensorThreshold = 300; // For connected sensors the value read (when turned on) should be below threshold. Used to detect if sensor connecte
      const int secondsSleep = 60; // amount of seconds RedBear Duo should go to sleep

      const String seperator = ","; // seperator to be used

      String sensorName = "Patch0/Sensor"; // Sensorname to send to Particle.io Cloud
      String sensorReadings = ""; // holds the sensor readings per loop

      //
      // Sensor Array Configuration
      //
      int moistureSensorSetup[7][2] = {{D0,A0},{D1,A1},{D2,A2},{D3,A3},{D4,A4},{D5,A5},{D6,A6}}; // Digital (power on/off) and Analogue (read value) couples


      // bug in Particle Cloud for firmware 0.3.3 - LED_BUILTIN is not defined, hence below workaround
      // -- workaround start
      #ifndef LED_BUILTIN
      #define LED_BUILTIN 7
      #endif
      // -- workaround end

      void setup() {
      // Turn D7/LED_BULTIN on to indicate that reading/processing is taking place. Will be useful when putting setup into case to provide user feedback
      digitalWrite(LED_BUILTIN, HIGH);

      // loop through all sensors and set the PINs up
      for (int i = 0; i < numberOfSensors; i++) {
      // setup D as output to power esnor, and A as input to read the value
      pinMode(moistureSensorSetup[i][0],OUTPUT); // We are setting DX to outout
      // no need to set the ADC's as output - will be done implicit by analogRead()

      // test if sensor is connected - (values under the defined threshold when turned off)
      digitalWrite(moistureSensorSetup[i][0],LOW);

      // initialise SensorRead
      int sensorRead = 0;

      // only if Sensor is connected
      if (analogRead(moistureSensorSetup[i][1]) < sensorThreshold) {
      // turn the sensor on, by setting digital pin to high
      digitalWrite(moistureSensorSetup[i][0],HIGH);

      // wait for sensor to settle
      delay(settleIv);

      // read sensor value from Analog Port
      sensorRead = analogRead(moistureSensorSetup[i][1]);

      // turn sensor off
      digitalWrite(moistureSensorSetup[i][0],LOW);
      }

      // add a seperator to list if there has been a previous value
      if (sensorReadings != "") {
      sensorReadings = sensorReadings + seperator;
      }

      // append the sensor reading
      sensorReadings = sensorReadings + String(sensorRead);
      }

      // once all sensors have been read, publish sensor values to cloud
      Particle.publish(sensorName, sensorReadings, 3600, PRIVATE);

      // Turn D7/LED_BULTIN off to indicate process is done
      digitalWrite(LED_BUILTIN, LOW);

      // disable line below when developing, as otherwise it will go immediately to sleep post processing and will make
      // flashing difficult.
      //System.sleep(SLEEP_MODE_DEEP, 60);
      }

      // we are not doing anything in loop as waking from sleep will restart (startup executed again)
      void loop() {
      // intentionally empty
      }