Hi,
I hope somebody can help.
I've been building a weather station for a remote site using an ESP32 Wrover Dev kIt.
I've got it working the way I want but now have to chenge from WiFi to Ethernet due to site limitations, and can I get it to work??? No!
I have the w5500 connected correctly and using this sketch it connects to the network and can be pinged.
#include <Ethernet.h>
#include <WiFi.h>
#define ETH_SPI_SCS 5 // CS (Chip Select), Green
uint8_t baseMac[6];
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("Starting Ethernet connection...");
//Set the CS pin, required for ESP32 as the arduino default is different
Ethernet.init(ETH_SPI_SCS);
esp_read_mac(baseMac, ESP_MAC_ETH);
Serial.print("Ethernet MAC: ");
for (int i = 0; i < 5; i++)
{
Serial.printf("%02X:", baseMac[i]);
}
Serial.printf("%02X\n", baseMac[5]);
//Start the Ethernet connection
Ethernet.begin(baseMac);
//Hardware check
Serial.println("Checking Ethernet hardware...");
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
Serial.println("ERROR: No Ethernet hardware detected!");
return;
}
else {
Serial.println("Ethernet hardware detected!");
}
//Check if cable is connected
if (Ethernet.linkStatus() == LinkOFF) {
Serial.println("Link is OFF. Check cable connection.");
}
else {
Serial.println("Link is ON. Cable is connected. Ready to go!");
Serial.println("DHCP OK!");
Serial.print("Local IP : ");
Serial.print("To test connection, please ping: ");
Serial.println(Ethernet.localIP());
Serial.println("Using hardwired ethernet");
}
}
void loop() {
// put your main code here, to run repeatedly:
}
This uses the ESP's WiFi MAC address as the ethernet MAC (they'll never be used together) and DHCP works BUT when I convert the main sketch to Ethernet it compiles but cant get the time and goes no further..
I'm no programmer so please be gentle with me if I've made stupid errors..
#include <Arduino.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <WiFi.h>
#include <SPI.h>
#include <Wire.h>
#include <time.h>
#include <HTTPClient.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <I2C_LCD.h>
//#include "Adafruit_SSD1306.h"
#include "Adafruit_GFX.h"
#include <OneWire.h>
#include <DallasTemperature.h>
#include <ZMPT101B.h>
#include <ThingSpeak.h>
#define SENSITIVITY 500.0f
#define ETH_SPI_SCS 5 // Ethernet CS (Chip Select)
//#define SCREEN_WIDTH 128 // OLED display width, in pixels
//#define SCREEN_HEIGHT 32 // OLED display height, in pixels
//#define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin)
//#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
//Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
//#define SEALEVELPRESSURE_HPA (1013.25)
//ZMPT101B sensor output connected to ADC pin 34
// and the source freq is 50 Hz
ZMPT101B voltageSensor(36, 50.0);
Adafruit_BME280 bme; // I2C
unsigned long delayTime;
int t = 0;
// GPIO 17 where the relay is connected
const int relay = 26; // 26 is relay control
// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long debounceDelay = 1000; // the debounce time; increase if the output flickers
int pinInterrupt = 15;
int Count=0;
int wspdcms = 0;
int wspdmph = ((Count*8.75)*0.0223694);
/////////////////////////////////////////////////
// GPIO where the DS18B20 is connected to
const int oneWireBus = 27;
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(oneWireBus);
DallasTemperature sensors(&oneWire);
// Change to your WiFi credentials and select your time zone
//const char* ssid = "your_SSID";
//const char* password = "your_PASSWORD";
EthernetClient client;
unsigned long myChannelNumber = xxxxxxx;
const char * myWriteAPIKey = "yyyyyyyy";
// Timer variables
unsigned long lastTime = 0;
//unsigned long timerDelay = 600000;
unsigned long timerDelay = 60000;
I2C_LCD lcd(39);
const char* Timezone = "GMT0BST,M3.5.0/01,M10.5.0/02"; // UK, see below for others and link to database
String Format = "X"; // Time format M for dd-mm-yy and 23:59:59, "I" for mm-dd-yy and 12:59:59 PM, "X" for Metric units but WSpeed in MPH
uint8_t baseMac[6];
static String Date_str, Time_str;
volatile unsigned int local_Unix_time = 0, next_update_due = 0;
volatile unsigned int update_duration = 60 * 30; // Time duration in seconds, so synchronise every halfhour
static float bme_temp, bme_humi, bme_pres, WindSpeed;// temperatureC;
static unsigned int Last_Event_Time;
//#########################################################################################
void IRAM_ATTR Timer_TImeout_ISR()
{
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
portENTER_CRITICAL_ISR(&timerMux);
local_Unix_time++;
portEXIT_CRITICAL_ISR(&timerMux);
}
//#########################################################################################
void onChange()
{
if ( digitalRead(pinInterrupt) == LOW )
Count++;
}
//#############################################
void setup()
{
Serial.begin(115200);
pinMode (relay, OUTPUT);
StartEthernet();
// Windspeed setup
pinMode( pinInterrupt, INPUT_PULLUP);// set the interrupt pin
//Enable
attachInterrupt( digitalPinToInterrupt(pinInterrupt), onChange, FALLING);
//#########################
// Set configurations before initialization
// Start the DS18B20 sensor
sensors.begin();
voltageSensor.setSensitivity(SENSITIVITY);
//ThingSpeak.begin(client); // Initialize ThingSpeak
Wire.begin(SDA, SCL, 100000); // (sda,scl,bus_speed) Start the Wire service for the OLED display using pin=D4 for SCL and Pin-D3 for SDA
bool status = bme.begin(0x76); // For Adafruit sensors use address 0x77, for most 3rd party types use address 0x76
if (!status) Serial.println("Could not find a valid BME280 sensor, check wiring!"); // Check for a sensor
lcd.begin(20,4);
lcd.display();
lcd.clear();
//display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
//display.clearDisplay();
//display.setTextColor(WHITE);
ThingSpeak.begin(client); // Initialize ThingSpeak
delay (2000);
Start_Time_Services();
Setup_Interrupts_and_Initialise_Clock(); // Now setup a timer interrupt to occur every 1-second, to keep seconds accurate
/* for (int index = 0; index < WS_Samples; index++)
{ // Now clear the Wind Speed average array
WSpeedReadings[index] = 0;
}
*/
}
//#########################################################################################
void loop()
{
sensors.requestTemperatures(); // Gets External Temp
UpdateLocalTime(); // The variables 'Date_str' and 'Time_str' now have current date-time values
BME280_Read_Sensor(); // The variables 'bme_temp', 'bme_humi', 'bme_pres' now have current values
float temperatureC = sensors.getTempCByIndex(0);
float temperatureF = sensors.getTempFByIndex(0);
// AC Voltage detector
float ACvoltage = voltageSensor.getRmsVoltage();
Serial.println(ACvoltage);
if (ACvoltage < 180)
{
//digitalWrite(relay, HIGH); //relay = high;
Serial.println("Low AC Voltage");
}
else
{
//digitalWrite(relay, LOW);
}
// Windspeed calculations
if ((millis() - lastDebounceTime) > debounceDelay)
{
lastDebounceTime = millis();
wspdcms=(Count*8.75);
wspdmph=((Count*8.75)* 0.0223694);
Serial.print(wspdmph);
Count=0;
Serial.println("mph");
}
//display.clearDisplay();
//display.setTextSize(1);
//display.setCursor(0,0);
//display.print(Date_str); // Display current date
//display.setCursor(70,0);
//display.print(Time_str);
lcd.setCursor(0, 0);
lcd.print(Date_str);
lcd.setCursor (12, 0);
lcd.print(Time_str);
lcd.display();
//display.display();
/* display.setCursor (5,10);
display.print(bme.readTemperature());
display.print("c");
display.setCursor (75,10);
display.print(bme.readHumidity());
display.print("%");
display.setCursor(10,24);
display.print(temperatureC);
display.print("c");
*/
lcd.setCursor(0, 1);
lcd.print("T");
lcd.setCursor(2, 1);
lcd.print(bme.readTemperature());
lcd.print("c");
lcd.setCursor(12, 1);
lcd.print("H");
lcd.setCursor(14, 1);
lcd.print(bme.readHumidity());
lcd.print("%");
lcd.setCursor(6,2);
lcd.print("External");
lcd.setCursor(0,3);
lcd.print("T ");
lcd.setCursor(2,3);
lcd.print(temperatureC);
lcd.print("c");
lcd.setCursor(12,3);
lcd.print("W");
lcd.setCursor(14,3);
lcd.print(" ");
lcd.setCursor(14,3);
lcd.print(wspdmph);
lcd.display();
//display.display();
GoToT_Spk();
delay(5000); // Small arbitrary delay
}
//#########################################################################################
void UpdateLocalTime()
{
time_t now;
if (local_Unix_time > next_update_due)
{ // only get a time synchronisation from the NTP server at the update-time delay set
time(&now);
Serial.println("Synchronising local time, time error was: " + String(now - local_Unix_time));
// If this displays a negative result the interrupt clock is running fast or positive running slow
local_Unix_time = now;
next_update_due = local_Unix_time + update_duration;
}
else now = local_Unix_time;
//See http://www.cplusplus.com/reference/ctime/strftime/
char hour_output[30], day_output[30];
if (Format == "M" || Format == "X")
{
strftime(day_output, 30, "%d-%m-%y", localtime(&now)); // Formats date as: 24-05-17
strftime(hour_output, 30, "%T", localtime(&now)); // Formats time as: 14:05:49
}
else
{
strftime(day_output, 30, "%m-%d-%y", localtime(&now)); // Formats date as: 05-24-17
strftime(hour_output, 30, "%r", localtime(&now)); // Formats time as: 2:05:49pm
}
Date_str = day_output;
Time_str = hour_output;
}
//#########################################################################################
void StartEthernet()
{
Serial.println("Starting Ethernet connection...");
//Set the CS pin, required for ESP32 as the arduino default is different
Ethernet.init(ETH_SPI_SCS);
esp_read_mac(baseMac, ESP_MAC_ETH);
Serial.print("Ethernet MAC: ");
for (int i = 0; i < 5; i++)
{
Serial.printf("%02X:", baseMac[i]);
}
Serial.printf("%02X\n", baseMac[5]);
//Start the Ethernet connection
Ethernet.begin(baseMac);
//Hardware check
Serial.println("Checking Ethernet hardware...");
if (Ethernet.hardwareStatus() == EthernetNoHardware)
{
Serial.println("ERROR: No Ethernet hardware detected!");
return;
}
else
{
Serial.println("Ethernet hardware detected!");
}
//Check if cable is connected
if (Ethernet.linkStatus() == LinkOFF)
{
Serial.println("Link is OFF. Check cable connection.");
}
else
{
Serial.println("Link is ON. Cable is connected. Ready to go!");
Serial.println("DHCP OK!");
Serial.print("Local IP : ");
//Serial.print("To test connection, please ping: ");
Serial.println(Ethernet.localIP());
Serial.println("Using hardwired ethernet");
Serial.print("Gateway IP : ");
Serial.println(Ethernet.gatewayIP());
Serial.print("DNS Server : ");
Serial.println(Ethernet.dnsServerIP());
}
}
//###################################################################
/*void StartWiFi()
{
WiFi.mode(WIFI_STA);
Serial.print(F("\r\nConnecting to: ")); Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED ) {
delay(500);
Serial.print(F("."));
}
Serial.print("WiFi connected to address: "); Serial.println(WiFi.localIP());
}*/
//#########################################################################################
void Setup_Interrupts_and_Initialise_Clock()
{
hw_timer_t * timer = NULL;
timer = timerBegin(0, 80, true);
timerAttachInterrupt(timer, &Timer_TImeout_ISR, true);
timerAlarmWrite(timer, 1000000, true);
timerAlarmEnable(timer);
//Now get current Unix time and assign the value to local Unix time counter and start the clock.
struct tm timeinfo;
while (!getLocalTime(&timeinfo))
{
Serial.println(F("Failed to obtain time"));
}
time_t now;
time(&now);
local_Unix_time = now + 1; // The addition of 1 counters the NTP setup time delay
next_update_due = local_Unix_time + update_duration;
}
//#########################################################################################
void Start_Time_Services()
{
// Now configure time services
configTime(0, 0, "pool.ntp.org", "time.nist.gov");
setenv("TZ", Timezone, 1); // See below for other time zones
delay(1000); // Wait for time services
}
//#########################################################################################
void BME280_Read_Sensor()
{
if (Format == "M" || Format == "X") bme_temp = bme.readTemperature();
else bme_temp = bme.readTemperature() * 9.00F / 5.00F + 32;
// if (Format == "M" || Format == "X") bme_pres = bme.readPressure() / 100.0F + pressure_offset;
//else bme_pres = (bme.readPressure() / 100.0F + pressure_offset) / 33.863886666667; // For inches
bme_humi = bme.readHumidity();
}
//###########################################################
void GoToT_Spk()
{
ThingSpeak.setField(1, bme.readTemperature());
ThingSpeak.setField(2, bme.readHumidity());
ThingSpeak.setField(3, sensors.getTempCByIndex(0));
ThingSpeak.setField(4, (wspdmph));
if ((millis() - lastTime) > timerDelay)
{
// Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different
// pieces of information in a channel. Here, we write to field 1.
int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);
//uncomment if you want to get temperature in Fahrenheit
//int x = ThingSpeak.writeField(myChannelNumber, 1, temperatureF, myWriteAPIKey);
if(x == 200){
Serial.println("Channel update successful.");
}
else{
Serial.println("Problem updating channel. HTTP error code " + String(x));
}
lastTime = millis();
}
}
//############################################################
// * Example time zones see: https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv
//const char* Timezone = "GMT0BST,M3.5.0/01,M10.5.0/02"; // UK
//const char* Timezone = "MET-2METDST,M3.5.0/01,M10.5.0/02"; // Most of Europe
//const char* Timezone = "CET-1CEST,M3.5.0,M10.5.0/3"; // Central Europe
//const char* Timezone = "EST-2METDST,M3.5.0/01,M10.5.0/02"; // Most of Europe
//const char* Timezone = "EST5EDT,M3.2.0,M11.1.0"; // EST USA
//const char* Timezone = "CST6CDT,M3.2.0,M11.1.0"; // CST USA
//const char* Timezone = "MST7MDT,M4.1.0,M10.5.0"; // MST USA
//const char* Timezone = "NZST-12NZDT,M9.5.0,M4.1.0/3"; // Auckland
//const char* Timezone = "EET-2EEST,M3.5.5/0,M10.5.5/0"; // Asia
//const char* Timezone = "ACST-9:30ACDT,M10.1.0,M4.1.0/3": // Australia
Bob