Using claud.ai to create Arduino code
I never thought I’d use an AI for coding, that said here is a plug and play bit of Claude code. Nice and neat I’ve found it’s a great starting place even if it needs tweaking.
Amazingly it (almost) worked first time !
To be fair I haven't connect the relay drivers yet, seems it needs a wee tweak there.
{"solar_controller": 1, "inverter_power": 0, "boost_charger": 1}
Data in MQTT
Actual data in node red
No wonder I got made redundant 
Arduino Nano - Data Acquisition and Control System
The prompt
I want a data acquisition system based on an Arduino nano with the following inputs battery voltage, solar charge current, boost charge current, Mains voltage which will come from an analogue device as a voltage. I also want athe following digital outputs. Solar charge controller on, inverter power on, boost charger on. The output data should be packaged as json and sent via the serial port to a esp8266 which will act as the network adaptor and send the data via Mqtt. Command's will be sent to the esp8266 using Mqtt and then sent via serial to The Arduino nano which will need to catch this data and act on it switching outputs etc. all data will be sent as raw bits in the json packets. I need sketches for both the esp8266 and the arduino nano
Claude said
I'll create comprehensive sketches for both the Arduino Nano (data acquisition and control) and the ESP8266 (network adapter with MQTT).
Arduino Nano - Data Acquisition System
Code
/* * Arduino Nano - Data Acquisition and Control System * Reads analog inputs, controls digital outputs * Communicates via JSON over Serial with ESP8266 */ #include <ArduinoJson.h> // Analog Input Pins const int PIN_BATTERY_VOLTAGE = A0; const
ESP8266 - MQTT Network Adapter
Code
/* * ESP8266 - MQTT Network Adapter * Bridges serial communication from Arduino Nano to MQTT * Receives commands via MQTT and forwards to Arduino Nano */ #include <ESP8266WiFi.h> #include <PubSubClient.h> #include <ArduinoJson.h> // WiFi creden
I've created both sketches for your data acquisition system. Here's what each does:
Arduino Nano Sketch
Features:
-
Reads 4 analog inputs (battery voltage, solar current, boost current, mains voltage) as raw ADC values (0-1023)
-
Controls 3 digital outputs (solar controller, inverter power, boost charger)
-
Sends data as JSON every second via serial
-
Receives commands via serial and controls outputs accordingly
-
Includes error handling and acknowledgments
ESP8266 Sketch
Features:
-
Connects to WiFi and MQTT broker
-
Forwards data from Arduino to MQTT topic daq/data
-
Subscribes to daq/command topic for control commands
-
Publishes status messages to daq/status topic
-
Validates JSON before forwarding
-
Auto-reconnects to WiFi and MQTT if connection lost
Setup Instructions:
1. Install Required Libraries:
-
Arduino Nano: ArduinoJson (install via Library Manager)
-
ESP8266: ESP8266WiFi, PubSubClient, ArduinoJson
2. Configure ESP8266:
-
Update WiFi credentials (WIFI_SSID, WIFI_PASSWORD)
-
Update MQTT broker settings (MQTT_BROKER, MQTT_PORT)
-
Add username/password if your broker requires authentication
3. Wiring:
-
Connect Arduino TX to ESP8266 RX
-
Connect Arduino RX to ESP8266 TX
-
Share common ground between devices
4. MQTT Command Format:
json
{"solar_controller": 1, "inverter_power": 0, "boost_charger": 1}
5. Data Output Format:
json
{
"battery_voltage": 512,
"solar_current": 256,
"boost_current": 128,
"mains_voltage": 768,
"solar_controller": 1,
"inverter_power": 0,
"boost_charger": 1,
"timestamp": 12345
}
The system sends raw ADC bits as you requested. To convert to actual voltage: voltage = (raw_value * 5.0) / 1023.0
/*
* Arduino Nano - Data Acquisition and Control System
* Reads analog inputs, controls digital outputs
* Communicates via JSON over Serial with ESP8266
*/
#include <ArduinoJson.h>
// Analog Input Pins
const int PIN_BATTERY_VOLTAGE = A0;
const int PIN_SOLAR_CURRENT = A1;
const int PIN_BOOST_CURRENT = A2;
const int PIN_MAINS_VOLTAGE = A3;
// Digital Output Pins
const int PIN_SOLAR_CONTROLLER = 2;
const int PIN_INVERTER_POWER = 3;
const int PIN_BOOST_CHARGER = 4;
// Timing
unsigned long lastSendTime = 0;
const unsigned long SEND_INTERVAL = 1000; // Send data every 1 second
// ADC to voltage conversion (Arduino Nano: 5V reference, 10-bit ADC)
const float ADC_REF_VOLTAGE = 5.0;
const int ADC_RESOLUTION = 1023;
void setup() {
// Initialize Serial communication with ESP8266
Serial.begin(115200);
// Configure analog input pins
pinMode(PIN_BATTERY_VOLTAGE, INPUT);
pinMode(PIN_SOLAR_CURRENT, INPUT);
pinMode(PIN_BOOST_CURRENT, INPUT);
pinMode(PIN_MAINS_VOLTAGE, INPUT);
// Configure digital output pins
pinMode(PIN_SOLAR_CONTROLLER, OUTPUT);
pinMode(PIN_INVERTER_POWER, OUTPUT);
pinMode(PIN_BOOST_CHARGER, OUTPUT);
// Initialize outputs to OFF
digitalWrite(PIN_SOLAR_CONTROLLER, LOW);
digitalWrite(PIN_INVERTER_POWER, LOW);
digitalWrite(PIN_BOOST_CHARGER, LOW);
// Wait for serial to initialize
delay(100);
}
void loop() {
// Check for incoming commands from ESP8266
if (Serial.available() > 0) {
processCommand();
}
// Send data at regular intervals
unsigned long currentTime = millis();
if (currentTime - lastSendTime >= SEND_INTERVAL) {
sendData();
lastSendTime = currentTime;
}
}
void sendData() {
// Read analog inputs (raw ADC values 0-1023)
int batteryVoltageRaw = analogRead(PIN_BATTERY_VOLTAGE);
int solarCurrentRaw = analogRead(PIN_SOLAR_CURRENT);
int boostCurrentRaw = analogRead(PIN_BOOST_CURRENT);
int mainsVoltageRaw = analogRead(PIN_MAINS_VOLTAGE);
// Read digital output states
int solarControllerState = digitalRead(PIN_SOLAR_CONTROLLER);
int inverterPowerState = digitalRead(PIN_INVERTER_POWER);
int boostChargerState = digitalRead(PIN_BOOST_CHARGER);
// Create JSON document
StaticJsonDocument<256> doc;
// Add analog readings (raw ADC values)
doc["battery_voltage"] = batteryVoltageRaw;
doc["solar_current"] = solarCurrentRaw;
doc["boost_current"] = boostCurrentRaw;
doc["mains_voltage"] = mainsVoltageRaw;
// Add digital output states
doc["solar_controller"] = solarControllerState;
doc["inverter_power"] = inverterPowerState;
doc["boost_charger"] = boostChargerState;
// Add timestamp
doc["timestamp"] = millis();
// Serialize and send
serializeJson(doc, Serial);
Serial.println(); // Add newline for message delimiter
}
void processCommand() {
// Read JSON command from serial
String jsonString = Serial.readStringUntil('\n');
// Parse JSON
StaticJsonDocument<200> doc;
DeserializationError error = deserializeJson(doc, jsonString);
if (error) {
// Send error response
StaticJsonDocument<100> errorDoc;
errorDoc["error"] = "JSON parse failed";
errorDoc["code"] = error.c_str();
serializeJson(errorDoc, Serial);
Serial.println();
return;
}
// Process commands
bool changed = false;
if (doc.containsKey("solar_controller")) {
int value = doc["solar_controller"];
digitalWrite(PIN_SOLAR_CONTROLLER, value ? HIGH : LOW);
changed = true;
}
if (doc.containsKey("inverter_power")) {
int value = doc["inverter_power"];
digitalWrite(PIN_INVERTER_POWER, value ? HIGH : LOW);
changed = true;
}
if (doc.containsKey("boost_charger")) {
int value = doc["boost_charger"];
digitalWrite(PIN_BOOST_CHARGER, value ? HIGH : LOW);
changed = true;
}
// Send acknowledgment
if (changed) {
StaticJsonDocument<100> ackDoc;
ackDoc["status"] = "ok";
ackDoc["message"] = "Command executed";
serializeJson(ackDoc, Serial);
Serial.println();
}
}
/*
* ESP8266 - MQTT Network Adapter
* Bridges serial communication from Arduino Nano to MQTT
* Receives commands via MQTT and forwards to Arduino Nano
*/
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
// WiFi credentials
const char* WIFI_SSID = "YourWiFiSSID";
const char* WIFI_PASSWORD = "YourWiFiPassword";
// MQTT Broker settings
const char* MQTT_BROKER = "mqtt.example.com"; // Change to your broker
const int MQTT_PORT = 1883;
const char* MQTT_CLIENT_ID = "ESP8266_DAQ";
const char* MQTT_USERNAME = ""; // Leave empty if not required
const char* MQTT_PASSWORD = ""; // Leave empty if not required
// MQTT Topics
const char* TOPIC_DATA = "daq/data"; // Publishes sensor data
const char* TOPIC_COMMAND = "daq/command"; // Subscribes to commands
const char* TOPIC_STATUS = "daq/status"; // Publishes system status
WiFiClient espClient;
PubSubClient mqttClient(espClient);
// Timing
unsigned long lastReconnectAttempt = 0;
const unsigned long RECONNECT_INTERVAL = 5000;
void setup() {
// Initialize serial communication with Arduino Nano
Serial.begin(115200);
// Connect to WiFi
setupWiFi();
// Configure MQTT
mqttClient.setServer(MQTT_BROKER, MQTT_PORT);
mqttClient.setCallback(mqttCallback);
mqttClient.setBufferSize(512); // Increase buffer if needed
}
void loop() {
// Maintain MQTT connection
if (!mqttClient.connected()) {
unsigned long now = millis();
if (now - lastReconnectAttempt > RECONNECT_INTERVAL) {
lastReconnectAttempt = now;
if (reconnectMQTT()) {
lastReconnectAttempt = 0;
}
}
} else {
mqttClient.loop();
}
// Check for data from Arduino Nano
if (Serial.available() > 0) {
processArduinoData();
}
}
void setupWiFi() {
delay(10);
Serial.println();
Serial.print("Connecting to WiFi: ");
Serial.println(WIFI_SSID);
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 30) {
delay(500);
Serial.print(".");
attempts++;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println();
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
} else {
Serial.println();
Serial.println("WiFi connection failed");
}
}
boolean reconnectMQTT() {
Serial.print("Attempting MQTT connection...");
boolean connected;
if (strlen(MQTT_USERNAME) > 0) {
connected = mqttClient.connect(MQTT_CLIENT_ID, MQTT_USERNAME, MQTT_PASSWORD);
} else {
connected = mqttClient.connect(MQTT_CLIENT_ID);
}
if (connected) {
Serial.println("connected");
// Subscribe to command topic
mqttClient.subscribe(TOPIC_COMMAND);
// Publish status
StaticJsonDocument<100> statusDoc;
statusDoc["status"] = "online";
statusDoc["client"] = MQTT_CLIENT_ID;
String statusJson;
serializeJson(statusDoc, statusJson);
mqttClient.publish(TOPIC_STATUS, statusJson.c_str(), true); // Retained message
} else {
Serial.print("failed, rc=");
Serial.print(mqttClient.state());
Serial.println(" retrying in 5 seconds");
}
return connected;
}
void mqttCallback(char* topic, byte* payload, unsigned int length) {
// Convert payload to string
String message;
for (unsigned int i = 0; i < length; i++) {
message += (char)payload[i];
}
Serial.print("MQTT message received on topic: ");
Serial.println(topic);
Serial.print("Message: ");
Serial.println(message);
// If it's a command, forward to Arduino Nano
if (strcmp(topic, TOPIC_COMMAND) == 0) {
forwardCommandToArduino(message);
}
}
void forwardCommandToArduino(String command) {
// Validate JSON before forwarding
StaticJsonDocument<200> doc;
DeserializationError error = deserializeJson(doc, command);
if (error) {
Serial.println("Invalid JSON command, not forwarding");
// Publish error to MQTT
StaticJsonDocument<100> errorDoc;
errorDoc["error"] = "Invalid JSON in command";
String errorJson;
serializeJson(errorDoc, errorJson);
mqttClient.publish(TOPIC_STATUS, errorJson.c_str());
return;
}
// Forward to Arduino Nano
Serial.println(command);
Serial.println(); // Ensure newline delimiter
}
void processArduinoData() {
// Read line from Arduino
String jsonString = Serial.readStringUntil('\n');
if (jsonString.length() == 0) {
return;
}
// Validate JSON
StaticJsonDocument<512> doc;
DeserializationError error = deserializeJson(doc, jsonString);
if (error) {
Serial.print("Failed to parse JSON from Arduino: ");
Serial.println(error.c_str());
return;
}
// Check if it's an error/ack message or data
if (doc.containsKey("error") || doc.containsKey("status")) {
// Publish to status topic
String outputJson;
serializeJson(doc, outputJson);
mqttClient.publish(TOPIC_STATUS, outputJson.c_str());
} else {
// Publish sensor data to data topic
String outputJson;
serializeJson(doc, outputJson);
mqttClient.publish(TOPIC_DATA, outputJson.c_str());
}
}