Analog pin not reading - boron via arduino ide

Hi I need some help please,

I cannot get my boron to read on analog pin A1, tried different pins but still no reading. I have tested the pin with multimeter and there is voltage.

Context: Code written in Arduino IDE, then copied in the particle console Web IDE, am using Blynk library to control via blynk app.

Your help would be greatly appreciated - tried everything I can think of and I’ve run out of ideas.

Please see code below:

// This #include statement was automatically added by the Particle IDE.
#include <Adafruit_DHT.h>

// This #include statement was automatically added by the Particle IDE.
#include <blynk.h>


/*************************************************************
  Blynk is a platform with iOS and Android apps to control
  Arduino, Raspberry Pi and the likes over the Internet.
  You can easily build graphic interfaces for all your
  projects by simply dragging and dropping widgets.

    Downloads, docs, tutorials: http://www.blynk.cc
    Sketch generator:           http://examples.blynk.cc
    Blynk community:            http://community.blynk.cc
    Follow us:                  http://www.fb.com/blynkapp
                                http://twitter.com/blynk_app

  Blynk library is licensed under MIT license
  This example code is in public domain.

 *************************************************************

  No coding required for direct digital/analog pin operations!

 *************************************************************/

#define BLYNK_PRINT Serial  // Set serial output for debug prints
//#define BLYNK_DEBUG       // Uncomment this to see detailed prints

/* Fill-in your Template ID (only if using Blynk.Cloud) */
//#define BLYNK_TEMPLATE_ID   "YourTemplateID"


// Uncomment this, if you want to set network credentials
//#include "cellular_hal.h"
//STARTUP(cellular_credentials_set("broadband", "", "", NULL));

// Run "ping blynk-cloud.com", and set Blynk IP to the shown address
#define BLYNK_IP        IPAddress(45,55,130,102)

// Set Blynk hertbeat interval.
// Each heartbeat uses ~90 bytes of data.
#define BLYNK_HEARTBEAT 60

// Set Particle keep-alive ping interval.
// Each ping uses 121 bytes of data.
#define PARTICLE_KEEPALIVE 20


// This #include statement was automatically added by the Particle IDE.
#include <blynk.h>

// This #include statement was automatically added by the Particle IDE.

#include "Adafruit_DHT.h"

//DHT 11 CONFIGURATION

// Example testing sketch for various DHT humidity/temperature sensors
// Written by ladyada, public domain

#define DHTPIN D1     // what pin we're connected to


//#define DHTTYPE DHT11    // DHT 11 
#define DHTTYPE DHT22   // DHT 22 (AM2302)
//#define DHTTYPE DHT21   // DHT 21 (AM2301)

// Connect pin 1 (on the left) of the sensor to +5V
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor

DHT dht(DHTPIN, DHTTYPE);


// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";

BlynkTimer timer;


//PINS

int Relay1_Pin = D9;
int Relay2_Pin = D2;
int Relay3_Pin = D3;
int Relay4_Pin = D4;
int Relay5_Pin = D5;
int Relay6_Pin = D6;
int Relay7_Pin = D7;
int Relay8_Pin = D8;

int Voltage_Battery_1_Pin = A1;
int Voltage_Battery_2_Pin = A5;

int Voltage_Battery_1_RAW = 0;
int Voltage_Battery_2_RAW = 0;

float Voltage_Battery_1 = 0;
float Voltage_Battery_2 = 0;

float DHT11_Temperature = 0;

void setup() {
    Serial.begin(115200); 
  Serial.println("Particle Boron Step UP Stage");
  
  //pinMode(Voltage_Battery_1_Pin , INPUT);
//    pinMode(Voltage_Battery_2_Pin , INPUT);
    
    pinMode(Relay1_Pin, OUTPUT);
    pinMode(Relay2_Pin, OUTPUT);
    pinMode(Relay3_Pin, OUTPUT);
    pinMode(Relay4_Pin, OUTPUT);
    pinMode(Relay5_Pin, OUTPUT);
    pinMode(Relay6_Pin, OUTPUT);
    pinMode(Relay7_Pin, OUTPUT);
    pinMode(Relay8_Pin, OUTPUT);
  
  
  
  Particle.keepAlive(PARTICLE_KEEPALIVE);
    Blynk.begin(auth, BLYNK_IP);
  DHT11_Setup_Stage();
  
  timer.setInterval(2000L, DHT11_Loop_Stage);
    timer.setInterval(2000L, Read_Battery_Voltages);
    timer.setInterval(5000L, UploadToCloud);
}

void loop() {
    Blynk.run();
    timer.run();
}

void UploadToCloud() {

  Blynk.virtualWrite(V5, Voltage_Battery_1);
  Blynk.virtualWrite(V6, Voltage_Battery_2);
  Blynk.virtualWrite(V7, DHT11_Temperature);
  
  //cont char * pointer from Int
  
  String Temperature = String(DHT11_Temperature);
  String Battery1 = String(Voltage_Battery_1_RAW);
  String Battery2 = String(Voltage_Battery_2_RAW);
  
  

    Particle.publish("temperatureStatus",Temperature,60,PRIVATE);
    Particle.publish("Battery1Status",Battery1,60,PRIVATE);
    Particle.publish("Battery2Status",Battery2,60,PRIVATE);
    
    
    delay(3000);


  

 // Particle.publish("battery1Status",Voltage_Battery_1,60,PRIVATE);
//  Particle.publish("battery2Status",Voltage_Battery_2,60,PRIVATE);


}


void Read_Battery_Voltages(){


    Voltage_Battery_1_RAW - digitalRead(Voltage_Battery_1_Pin);
    Voltage_Battery_2_RAW - digitalRead(Voltage_Battery_2_Pin);
    Serial.print("Voltage_Battery_1_RAW = ");
    Serial.println(Voltage_Battery_1_RAW);
    
    Serial.print("Voltage_Battery_2_RAW = ");
    Serial.println(Voltage_Battery_2_RAW);
    
    Voltage_Battery_1 = map(Voltage_Battery_1_RAW, 0, 1024, 0 , 12);
    Voltage_Battery_2 = map(Voltage_Battery_1_RAW, 0, 1024, 0 , 12);
    
    Serial.print("Voltage_Battery_1 = ");
    Serial.println(Voltage_Battery_1);
    
    Serial.print("Voltage_Battery_2 = ");
    Serial.println(Voltage_Battery_2);
    
    
}


void DHT11_Setup_Stage(){
  Serial.println("DHT11 test!");
  dht.begin();
}

void DHT11_Loop_Stage(){
    // Wait a few seconds between measurements.
  delay(1000);

// Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (its a 
// very slow sensor)
  float h = dht.getHumidity();
// Read temperature as Celsius
  float t = dht.getTempCelcius();
  
  DHT11_Temperature = t;
// Read temperature as Farenheit
  float f = dht.getTempFarenheit();
  
// Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

// Compute heat index
// Must send in temp in Fahrenheit!
  float hi = dht.getHeatIndex();
  float dp = dht.getDewPoint();
  float k = dht.getTempKelvin();

  Serial.print("Humid: "); 
  Serial.print(h);
  Serial.print("% - ");
  Serial.print("Temp: "); 
  Serial.print(t);
  Serial.print("*C ");
  Serial.print(f);
  Serial.print("*F ");
  Serial.print(k);
  Serial.print("*K - ");
  Serial.print("DewP: ");
  Serial.print(dp);
  Serial.print("*C - ");
  Serial.print("HeatI: ");
  Serial.print(hi);
  Serial.println("*C");
  Serial.println(Time.timeStr());
    
}

BLYNK_WRITE(V1)
{
  int pinValue = param.asInt(); // assigning incoming value from pin V1 to a variable
  // You can also use:
  // String i = param.asStr();
  // double d = param.asDouble();
  Serial.print("Relay 1 value is: ");
  Serial.println(pinValue);

  if (pinValue == 1){
    digitalWrite(Relay1_Pin, LOW);
    
  } else if(pinValue == 0){
    digitalWrite(Relay1_Pin, HIGH);
  }

}

BLYNK_WRITE(V2)
{
  int pinValue = param.asInt(); // assigning incoming value from pin V1 to a variable
  // You can also use:
  // String i = param.asStr();
  // double d = param.asDouble();
  Serial.print("Relay 2 value is: ");
  Serial.println(pinValue);

  if (pinValue == 1){
    digitalWrite(Relay2_Pin, LOW);
    
  } else if(pinValue == 0){
    digitalWrite(Relay2_Pin, HIGH);
  }

}


BLYNK_WRITE(V3)
{
  int pinValue = param.asInt(); // assigning incoming value from pin V1 to a variable
  // You can also use:
  // String i = param.asStr();
  // double d = param.asDouble();
  Serial.print("Relay 3 value is: ");
  Serial.println(pinValue);

  if (pinValue == 1){
    digitalWrite(Relay3_Pin, LOW);
    
  } else if(pinValue == 0){
    digitalWrite(Relay3_Pin, HIGH);
  }

}


BLYNK_WRITE(V4)
{
  int pinValue = param.asInt(); // assigning incoming value from pin V1 to a variable
  // You can also use:
  // String i = param.asStr();
  // double d = param.asDouble();
  Serial.print("Relay 4 value is: ");
  Serial.println(pinValue);

  if (pinValue == 1){
    digitalWrite(Relay4_Pin, LOW);
    
  } else if(pinValue == 0){
    digitalWrite(Relay4_Pin, HIGH);
  }

}

Are you using analogRead()? I cannot find it anywhere.
digitalRead() will only ever render results 0 or 1 which doesn’t make a lot of sense when then using map(x, 0, 1024, 0, 12) with that result.

If you are only using digitalRead() you may want to explicitly set pinMode().
Although the default should be INPUT relying on that isn’t best practice and no good idea IMHO.

BTW, on Particle devices the ADC (analogRead()) would render results in the range of 0…4095 not 0…1023 as it would with Arduino devices.
I’m also not sure whether you didn’t write this wrong

Why a subtraction and then not even catching the result?

I’d suspect you’d rather intended to write it like this, right?

    Voltage_Battery_1_RAW = analogRead(Voltage_Battery_1_Pin);
    Voltage_Battery_2_RAW = analogRead(Voltage_Battery_2_Pin);

I’d also rewrite this

as

  char msg[128];
  snprintf(msg, sizeof(msg)
          , "Temp: %5.1f °C, Bat1: %3.1f V, Bat2: %3.1f V"
          , DHT11_Temperature
          , Voltage_Battery_1
          , Voltage_Battery_2
          );
  Particle.publish("Status", msg);  
  delay(1000);

It’s usually better to package your publish data into a single event to save on data operations and also avoid frequent use of String to reduce the risk of heap fragmentation.

I suggest you also avoid copy/pasting the functionality of your BLYNK_WRITE(x) functions.
Have the active part packaged in a reusable function and then call that like this

const int relay[] = 
{ 0    // dummy for index 0
, D9   // Relay 1 at index 1
, D2   // Relay 2
, D3   // Relay 3 
, D4   // Relay 4 
, D5   // Relay 5 
, D6   // Relay 6 
, D7   // Relay 7 
, D8   // Relay 8 
};
const int nRelays = sizeof(relay) / sizeof(relay[0]);

void setup() {
  for (int p = 1; p < nRelays; p++)
    pinMode(relay[p], OUTPUT);
  ...
}

void pinWrite(int  pin, int val) {
  Serial.printlnf("Relay %d value is: %d", pin, val);
  digitalWrite(relay[pin], !val);
}
BLYNK_WRITE(V1) { pinWrite(1, param.asInt()); }
BLYNK_WRITE(V2) { pinWrite(2, param.asInt()); }
BLYNK_WRITE(V3) { pinWrite(3, param.asInt()); }
BLYNK_WRITE(V4) { pinWrite(4, param.asInt()); }

Above also shows the advantage of using arrays instead of a number of individual variables like RelayX_Pin as you can use loops and functions to avoid rewriting/copy-pasting code over and over.
When you add remove an entry from the initialization list the code in setup() will still work without any further ado.

2 Likes

Yes, I tried analog Read earlier and defined the pinmodes for A1 and A2 to make sure A1 wasn’t fried etc but it didn’t work on A2 either. I tested digital read because analog read wasn’t working and I ran out of things to try.

Have you seen the other points I added above?

What exactly was the problem with analogRead()?
I guess the main problem was the error of using a subtraction (-) where you should have used an assignment (=) :wink:

oops no, didn’t see it as It didn’t come through when I first looked.

Thank you, that makes a lot of sense, I will try that and let you know tomorrow.

Thank you gain, very much appreciated :smile:

1 Like

yes I meant to put “=” it was a typo

Thank you again

I took the liberty and reworked your project a bit and also replaced the DHT library with one that seems to work a bit more reliable with later device OS versions.
I hope this does what it should :wink:

#include <PietteTech_DHT.h>
#include <blynk.h>

STARTUP(Particle.keepAlive(20);)

#define BLYNK_PRINT        Serial 
#define BLYNK_IP           IPAddress(45,55,130,102)
#define BLYNK_HEARTBEAT    60

#define DHTTYPE  DHT22       // Sensor type DHT11/21/22/AM2301/AM2302
#define DHTPIN   D1          // Digital pin for communications
// Connect pin 1 (on the left) of the sensor to +5V
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor

const char auth[]   = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
   
// pin assignments
const int batt[]    = { A1, A5 };
const int relay[]   = 
{ 0    // dummy for index 0
, D9   // Relay 1 at index 1
, D2   // Relay 2
, D3   // Relay 3 
, D4   // Relay 4 
, D5   // Relay 5 
, D6   // Relay 6 
, D7   // Relay 7 
, D8   // Relay 8 
};
const int nRelays   = sizeof(relay) / sizeof(relay[0]);

float battVoltage[] = { 0.0, 0.0 };
float temp          = 0.0;

BlynkTimer          timer;
PietteTech_DHT      dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(115200); 
  Serial.println("Particle Boron Step UP Stage");
  
  for (int p = 1; p < nRelays; p++)
    pinMode(relay[p], OUTPUT);
 
  Blynk.begin(auth, BLYNK_IP);
  
  dhtSetup();
  
  timer.setInterval(2000L, dhtLoop);
  timer.setInterval(2000L, readBatteries);
  timer.setInterval(5000L, cloudUpload);
}

void loop() {
  Blynk.run();
  timer.run();
}

void cloudUpload() {
  Blynk.virtualWrite(V5, battVoltage[0]);
  Blynk.virtualWrite(V6, battVoltage[1]);
  Blynk.virtualWrite(V7, temp);
  
  char msg[128];
  snprintf(msg, sizeof(msg)
          , "Temp: %5.1f °C, Bat1: %3.1f V, Bat2: %3.1f V"
          , temp
          , battVoltage[0]
          , battVoltage[1]
          );
  Particle.publish("Status", msg);  
}

void readBatteries() {
  for (int b = 0; b < 2; b++) {
    battVoltage[b] = map((float)analogRead(batt[b]), 0.0, 4095.0, 0.0, 12.0);
    Serial.printlnf("Voltage Battery %d is %3.1f", b+1, battVoltage[b]);    
  }
}

void dhtSetup() {
  Serial.println("DHT test!");
  dht.begin();
}

void dhtLoop() {
  if (DHTLIB_OK == dht.acquireAndWait(1000)) {
    temp = dht.getCelsius();
    Serial.printlnf("Humidity   : %.1f %%\r\n"
                    "Temperature: %.1f°C\r\n"    
                    "             %.1f°F\r\n"    
                    "             %.1f K\r\n"    
                    "Dew Point  : %.1f°C\r\n"    
                    "Heat Index : %.1f°C\r\n"
                    "%s"
                   , dht.getHumidity()
                   , temp
                   , dht.getFahrenheit()
                   , dht.getKelvin()
                   , dht.getDewPoint()
                   , dht.CtoF(dht.getHeatIndex())
                   , (const char*)Time.timeStr()
                   );
  }
  else {
    Serial.printlnf("DHT read failed");
  }
}

void pinWrite(int  pin, int val) {
  Serial.printlnf("Relay %d value is: %d", pin, val);
  digitalWrite(relay[pin], !val);
}

BLYNK_WRITE(V1) { pinWrite(1, param.asInt()); }
BLYNK_WRITE(V2) { pinWrite(2, param.asInt()); }
BLYNK_WRITE(V3) { pinWrite(3, param.asInt()); }
BLYNK_WRITE(V4) { pinWrite(4, param.asInt()); }
2 Likes

Hi ScruffR,

I have installed the code that you kindly reworked - I can report that the both the voltages now work but the temp shows as 0.

Also the voltage is incorrect for the first reading it displays 8.8v a multimeter reads 11.6v.

I looked into the sensor again and it needed a 10k resistor between the pin 1 and pin 2 ie between the power and signal pins - now the temp works :slight_smile:

Now Just need to work out why the voltage readings are not accurate.

The code alone won’t tell the whole story for the battery reading.
We also need to know how you wired the voltage sensing.
Be aware that the ADCs on the Boron can only accept 0…3.3V (unlike many Arduinos which go up to 5V).
Anything above that will destroy them.

Since I received your schematic via PM I found that you are using a “voltage sensor” with a division factor of 5.
Consequently the voltage on the ADC when your battery supplies 12V will only be 2.4V which would be a raw analogRead() value of ~2980.

Hence you need to adapt your ADC mapping accordingly
e.g.

  battVoltage[b] = map((double)analogRead(batt[b]), 0.0, 2980.0, 0.0, 12.0);  
  // or based on the maximum allowed voltage 3.3V * 5 = 16.5V
  battVoltage[b] = map((double)analogRead(batt[b]), 0.0, 4095.0, 0.0, 16.5);  

Not sure why your Bat2 reports 12V tho’.
I’d put that down to a not yet fully finished HW setup as I doubt your battery would actually supply 16.5V in order to render that result with the previous (wrong) mapping.

I played with the mapping and i now have accurate readings :grinning:

My next challenge is to get it to work with MQTT mosquitto and node red so I can monitor and control it via a custom dashboard, both will be running on a Synology NAS running Docker.

The reason why I’m doing it this way is I don’t want any additional costs.

Also can the Boron use bluetooth as a backup if there is no cellular available ? if yes how do i code that ?

ScruffR,

You were correct, After adjusting the ADC mapping I went back and checked all the connections and found several were not tight - after tightening them, Bat2 Magically displayed the correct voltage :grinning:

This part of the project was a valuable learning experience, thanks to your help it was made a whole lot easier and saved me a lot of time.

Thank you ScruffR.

1 Like