I am revamping my Arduino Nano based voltmeter project by using a Arduino Nano 33 IOT.
I am aware the 33 IOT takes max 3.3 volts on the analog and digital inputs. However, I'm stranded right at the start of the project, because i can't get the A4 pin reading anywhere near zero volts, unless i short it to ground. I can't make it produce any meaningfull measures above 0V either.
Schematics:
- Arduino Nano 33 IOT powered via USB from pc
- A4 connected to the middle of a voltage divider: 12K to GND, 56K to the to be measured load.
- nothing else connected!
In this schematic, voltage at A4 is already 2.11 volts (analogRead giving me numbers around 650, i.e. already half past the 0 - 3.3 V range the pin can take. The only way i can lower this number is by using a smaller resistor to ground, but 1K still gives me readings of around 150. And, a voltage divider should always be constructed of relative high resistors.
If i apply voltage to the voltage divider, the excess voltage above this 'rest' voltage isn't measured properly either. A4 (and A0 and A1 i tried) don't behave anywhere near i am expecting. Does anyone have a clue?
my full code (work in progress)
#include <OneWire.h>
#include <string.h>
#include <DallasTemperature.h>
//#include <SoftwareSerial.h>
#include <SPI.h>
//#include <MemoryFree.h>
#include <ArduinoHttpClient.h>
#include <WiFiNINA.h>
#define ONE_WIRE_BUS 5
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
#define DEBUG 1
#if DEBUG == 1
#define debug(x) Serial.print(x)
#define debugln(x) Serial.println(x)
#else
#define debug(x)
#define debugln(x)
#endif
char ssid[] = "PP1"; // your network SSID (name)
char pass[] = "******"; // your network password (use for WPA, or use as key for WEP)
int status = WL_IDLE_STATUS; // the Wi-Fi radio's status
int ledState = LOW; //ledState used to set the LED
unsigned long previousMillisInfo = 0; //will store last time Wi-Fi information was updated
unsigned long previousMillisLED = 0; // will store the last time LED was updated
const int intervalInfo = 5000; // interval at which to update the board information
// Name of the server we want to connect to
const char kHostname[] = "*********";
int kPort = 8195;
const char kPath[] = "/json.htm?type=command¶m=getversion";
String serverName = "http://**********";
// Number of milliseconds to wait without receiving any data before we give up
const int kNetworkTimeout = 30 * 1000;
// Number of milliseconds to wait if no data is available before trying again
const int kNetworkDelay = 1000;
WiFiClient c;
HttpClient http(c, kHostname, kPort);
/****************************************************
Declare pins & variables
****************************************************/
int batMonPin = A4; // input pin for the voltage divider
int ampMonPin = A3; // input pin for the amperemeter
//int refMonPin = A6; // input pin for ref voltage 4.2 volt
float batteryVoltage = 0.00;
float ampoffset = 0.00;
float voltoffset = 0.1;
float accucapaciteit = 100;
float accuniveau = 100;
float amps = 0.00;
float batteryValues = 1;
float ampValues = 0;
//float refValues = 0;
float tempC1 = 20.0;
float tempC1min = 100.0;
float tempC1max = -100.0;
float tempC2 = 0.0;
float tempC2min = 100.0;
float tempC2max = -100.0;
float mem = 0;
float uptime = 0;
unsigned long Time1 = millis();
unsigned long Time2 = millis();
/****************************************************
Function reset
****************************************************/
void(* resetFunc) (void) = 0;
/****************************************************/
/********************************************************************************************************************************************************
Setup put your setup code here, to run once:
*******************************************************************************************************************************************************/
void setup() {
Serial.begin(9600); // for serial monitor
while (!Serial);
debugln("Powermonitor starting");
// Start up the DallasLibrary:
sensors.begin();
// attempt to connect to Wi-Fi network:
while (status != WL_CONNECTED) {
debug("Attempting to connect to network: ");
debugln(ssid);
// Connect to WPA/WPA2 network:
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
}
// you're connected now, so print out the data:
debugln("You're connected to the network");
debugln("---------------------------------------");
debugln(F("Einde setup"));
} // end setup
/********************************************************************************************************************************************************
Loop put your main code here, to run repeatedly:
*******************************************************************************************************************************************************/
void loop() {
/*** Section 1. Get the Values***********************************************************************************************************************************/
sensors.requestTemperatures();
tempC1 = sensors.getTempCByIndex(0) + 0.2; // the index 0 refers to the first device
tempC2 = sensors.getTempCByIndex(1); // the index 1 refers to the second device
// read analog power values
batteryValues = 1;
ampValues = 0;
// refValues = 0;
for (int x = 0; x < 20; x++) // run through loop 20 times
{
ampValues += analogRead(ampMonPin); // // add samples together
delay(10);
batteryValues += analogRead(batMonPin); // add samples together
delay (10); // let ADC settle before next sample
// refValues += analogRead(refMonPin); //refMionPin voltage is measured at 4.42V
// delay(10);
} //end 20 loop
// convert to milli amps. Sensor puts out 32mV per Ampere. Voltage at sensor at rest is around 2475 mV
batteryValues = batteryValues / 20;
// refValues = refValues / 20;
ampValues = ampValues / 20 - 570;
amps = ampoffset + ampValues * 0.067; //via afdrukken avgampvalue vastgesteld dat elke 0.066288 A een stap is.
batteryVoltage = voltoffset + batteryValues * 3.3 / 1024 * 5.643;
Time2 = millis();
if (Time2 > Time1) accuniveau = accuniveau + ((amps * (Time2 - Time1)) / 3600000 * (100 / accucapaciteit) ) ;
Time1 = Time2;
if (accuniveau > 100) accuniveau = 100;
if (accuniveau <= 0) accuniveau = 0;
uptime = (Time2 / 3600000);
// mem = freeMemory();
debug("batteryValues:");
debugln(batteryValues);
debug("batteryVoltage:");
debugln(batteryVoltage);
debug("ampValues:");
debugln(ampValues);
debug("amps:");
debugln(amps);
debug("accuniveau:");
debugln(accuniveau);
// debug("Free memory");
// debugln(mem);
debug("Uptime");
debugln(uptime);
// if (mem < 250) {
// debugln("Calling resetFunc");
// delay(1000);
// resetFunc();
// }
debugln("Board Information:");
// print your board's IP address:
IPAddress ip = WiFi.localIP();
debug("IP Address: ");
debugln(ip);
// print your network's SSID:
debugln();
debugln("Network Information:");
debug("SSID: ");
debugln(WiFi.SSID());
// print the received signal strength:
long rssi = WiFi.RSSI();
debug("signal strength (RSSI):");
debugln(rssi);
debugln("---------------------------------------");
int err = 0;
const char kPath[] = "/json.htm?type=command¶m=updateuservariable&vname=Powermonitor&vtype=2&vvalue=";
char kPath_string[100];
char semicolon[2] =";";
strcpy(kPath_string,kPath);
char buffer[15];
int ret = snprintf(buffer, sizeof buffer, "%.2f", batteryVoltage);
strcat(kPath_string, buffer);
strcat(kPath_string,semicolon);
Serial.println(kPath_string);
err = http.get(kPath_string);
if (err == 0)
{
Serial.println("startedRequest ok");
err = http.responseStatusCode();
if (err >= 0)
{
Serial.print("Got status code: ");
Serial.println(err);
// Usually you'd check that the response code is 200 or a
// similar "success" code (200-299) before carrying on,
// but we'll print out whatever response we get
// If you are interesting in the response headers, you
// can read them here:
//while(http.headerAvailable())
//{
// String headerName = http.readHeaderName();
// String headerValue = http.readHeaderValue();
//}
int bodyLen = http.contentLength();
Serial.print("Content length is: ");
Serial.println(bodyLen);
Serial.println();
Serial.println("Body returned follows:");
// Now we've got to the body, so we can print it out
unsigned long timeoutStart = millis();
char c;
// Whilst we haven't timed out & haven't reached the end of the body
while ( (http.connected() || http.available()) &&
(!http.endOfBodyReached()) &&
((millis() - timeoutStart) < kNetworkTimeout) )
{
if (http.available())
{
c = http.read();
// Print out this character
Serial.print(c);
// We read something, reset the timeout counter
timeoutStart = millis();
}
else
{
// We haven't got any data, so let's pause to allow some to
// arrive
delay(kNetworkDelay);
}
}
}
else
{
Serial.print("Getting response failed: ");
Serial.println(err);
}
}
else
{
Serial.print("Connect failed: ");
Serial.println(err);
}
delay(5000);
} // end main loop