Built-in project · Arduino Pro Mini, 3.3 V 8 MHz

Solar sensor node on a 3.3 V Arduino Pro Mini

A 6 V panel charges an 18650 through a TP4056, an MCP1700 makes 3.3 V, and a Pro Mini reports temperature, humidity, the battery and the panel every few seconds. The whole build, a 3.3 V Arduino Pro Mini and 9 more parts, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.

Runs in your browser. Free, and no account needed.

Solar sensor node · Arduino Pro Mini, 3.3 V 8 MHzlive0.000 s 0.00x
Click to open it in the editor
The circuit itself, running here on the simulator. Press what can be pressed; click anything else to open it in the editor.

The code

The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.

sketch.ino · Arduino Pro Mini, 3.3 V 8 MHz
// Solar sensor node: a 3.3 V Pro Mini and an AHT20 that live outdoors on a
// 6 V 1 W panel and one 18650 cell.
//
//   the panel      into the TP4056's IN+ and IN-
//   the 18650      on the TP4056's BAT+ and BAT-
//   MCP1700-3.3    IN from BAT+, OUT to the Pro Mini's VCC and the AHT20's VCC
//   A0             the middle of 100 k and 100 k from BAT+ to GND (half the cell)
//   A1             the middle of 100 k and 47 k from the panel's + to GND
//   A4, A5         SDA and SCL to the AHT20
//
// # The power path
//
// The panel is a current source set by the sun: about 0.2 A in full sun,
// whatever the cell wants. The TP4056 passes what it gets into the cell, up
// to 1 A, and stops at 4.2 V. The MCP1700 turns the cell's 3.0 to 4.2 V into
// 3.3 V with 178 mV of dropout and under 2 uA for itself, which is why it and
// not an AMS1117 (a volt of dropout, 5 mA for itself) is on a battery node.
// A Li-ion cell under 3.5 V is nearly empty and close to where the MCP1700
// can no longer make 3.3 V, so there the node stops measuring and waits for
// the sun.
//
// # Measuring its own supply
//
// The ADC's reference is VCC, 3.3 V, so the cell (up to 4.2 V) is halved and
// the panel (up to 7.2 V) is divided by 147/47 before they reach a pin. The
// sums are in millivolts and whole numbers.
//
// # Sleeping
//
// A real node sleeps between readings (LowPower.powerDown in the Rocket
// Scream library, a few microamps) and wakes on the watchdog. Here delay()
// stands in for the sleep, so the reports come at the same pace.

#include <Wire.h>
#include <Adafruit_AHTX0.h>

const int CELL = A0;
const int PANEL = A1;
const long VREF_MV = 3300;
const unsigned long EVERY_MS = 3000;
const long LOW_CELL_MV = 3500;

Adafruit_AHTX0 aht;
bool sensorOk = false;

long millivolts(int pin, long top, long bottom) {
  long sum = 0;
  for (int i = 0; i < 8; i++) sum += analogRead(pin);
  long mv = sum * VREF_MV / 8 / 1023;
  return mv * (top + bottom) / bottom;
}

// Hundredths, as a number with two places: 372 is 3.72.
void printCenti(long v) {
  Serial.print(v / 100);
  Serial.print('.');
  long frac = v % 100;
  if (frac < 10) Serial.print('0');
  Serial.print(frac);
}

void setup() {
  Serial.begin(57600);
  Serial.println("Mokxi Pro Mini 3.3 V: solar sensor node");
  Wire.begin();
  sensorOk = aht.begin();
  if (!sensorOk) Serial.println("no AHT20: check SDA, SCL and 3.3 V");
}

void loop() {
  long cell = millivolts(CELL, 100, 100);
  long panel = millivolts(PANEL, 100, 47);
  bool charging = panel > cell + 100;

  Serial.print("cell ");
  printCenti(cell / 10);
  Serial.print(" V  panel ");
  printCenti(panel / 10);
  Serial.print(charging ? " V  charging" : " V  not charging");

  if (cell < LOW_CELL_MV) {
    Serial.println("  cell low: waiting for the sun");
  } else if (sensorOk) {
    // One measurement. No events wanted: the whole numbers below are all
    // this sketch needs, and leaving out the floats keeps it small.
    aht.getEvent(NULL, NULL);
    long rh = (aht.getHumidityCentis() + 50) / 100;
    Serial.print("  ");
    printCenti(aht.getTemperatureCentis());
    Serial.print(" C  ");
    Serial.print(rh);
    Serial.println(" %RH");
  } else {
    Serial.println();
  }
  delay(EVERY_MS);
}

Parts list

11 parts, plus the jumper wires. Every one is in the editor's parts bin.

How it is wired

9 connections, pin by pin, read from the circuit itself. Each line is one set of pins joined together, by a jumper wire or a breadboard strip.

  • Ground: Arduino Pro Mini, 3.3 V 8 MHz pin GND; Li-ion charger, TP4056 pin BAT-; Battery, 9 V, AA or 18650 pin V-; Voltage regulator pin GND; Humidity sensor, AHT20 pin GND; Resistor, 100k Ω (2) pin 2; Resistor, 47k Ω pin 2
  • Arduino Pro Mini, 3.3 V 8 MHz pin VCC; Voltage regulator pin OUT; Humidity sensor, AHT20 pin VCC
  • Arduino Pro Mini, 3.3 V 8 MHz pin A1; Resistor, 100k Ω (3) pin 2; Resistor, 47k Ω pin 1
  • Arduino Pro Mini, 3.3 V 8 MHz pin A0; Resistor, 100k Ω (1) pin 2; Resistor, 100k Ω (2) pin 1
  • Arduino Pro Mini, 3.3 V 8 MHz pin A4; Humidity sensor, AHT20 pin SDA
  • Arduino Pro Mini, 3.3 V 8 MHz pin A5; Humidity sensor, AHT20 pin SCL
  • Solar panel, 6 V 1 W pin +; Li-ion charger, TP4056 pin IN+; Resistor, 100k Ω (3) pin 1
  • Solar panel, 6 V 1 W pin -; Li-ion charger, TP4056 pin IN-
  • Li-ion charger, TP4056 pin BAT+; Battery, 9 V, AA or 18650 pin V+; Voltage regulator pin IN; Resistor, 100k Ω (1) pin 1

Change it and keep it

Open it in the editor, change the circuit or the code, and keep your version in a free account.