2 Core with one ethernet module - arduino

I am using raspberry pi pico with earle's pico core earlepicocore. I am using W5500 with them and I am using this library for it khoih-prog/EthernetWebServer . I hava a lot of code like 1000+ line. I am doing http get and post request and then doing some stuff with these datas. I initialize W5500 ethernet on core 0. Here is my code ;
void setup()
{
uint16_t index = millis() % NUMBER_OF_MAC;
Ethernet.begin(mac[index], 1000);
}
void loop()
{
Serial.println("making GET request");
int statusCode = httpClient.responseStatusCode();
String response = httpClient.responseBody();
.
.
.
}
void setup1()
{
}
void loop1()
{
Serial.println("making GET request");
int statusCode = httpClient.responseStatusCode();
String response = httpClient.responseBody();
.
.
.
}
As I said, I can only use ethernet to activate in 1 core. When I activate it in 2 cores, an error occurs.
uint16_t index = millis() % NUMBER_OF_MAC;
Ethernet.begin(mac[index], 1000);
When I start the code, void loop1 can http request too but after a bit, W5500 give code -2 and -3. Errors :
// Could not connect to the server
static const int HTTP_ERROR_CONNECTION_FAILED = -1;
// This call was made when the EthernetHttpClient class wasn't expecting it
// to be called. Usually indicates your code is using the class
// incorrectly
static const int HTTP_ERROR_API = -2;
// Spent too long waiting for a reply
static const int HTTP_ERROR_TIMED_OUT = -3;
// The response from the server is invalid, is it definitely an HTTP
// server?
static const int HTTP_ERROR_INVALID_RESPONSE = -4;
So my question is, is this error appears because I am using ethernet on core 1 without initialize it ?
Thank you.

Related

How to change supervision timeout of ble device esp32

I am using two esp32, one configured as server and the other as client,the server takes about 3 seconds to detect disconnection of client (when it’s out of range or turned off), while client takes 6 seconds to detect disconnection of server, how do I set the supervision timeout so that Both sever and client detect disconnection after only 1 sec
Here’s the server code :
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
bool deviceConnected = false;
//Setup callbacks onConnect and onDisconnect
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
deviceConnected = true;
};
void onDisconnect(BLEServer* pServer) { // this method takes 6 sec when I’m using two esps (when esp client disconnects from server ) but it’s immediate when my phone disconnects from server
deviceConnected = false;
Serial.println("Client has disconnected");
Serial.println("readvertising");
BLEDevice::getAdvertising()->start(); // start advertising after disconnect
}
};
void setup() {
Serial.begin(115200);
Serial.println("Starting BLE work!");
BLEDevice::init("Long name works now");
BLEServer *pServer = BLEDevice::createServer();
BLEService *pService = pServer->createService(SERVICE_UUID);
BLECharacteristic *pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE
);
pCharacteristic->setValue("Hello World says Neil");
pService->start();
// BLEAdvertising *pAdvertising = pServer->getAdvertising(); // this still is working for backward compatibility
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID(SERVICE_UUID);
pAdvertising->setScanResponse(true);
pAdvertising->setMinPreferred(0x06); // functions that help with iPhone connections issue
pAdvertising->setMinPreferred(0x12);
BLEDevice::startAdvertising();
Serial.println("Characteristic defined! Now you can read it in your phone!");
}
void loop() {
// put your main code here, to run repeatedly:
if(deviceConnected){
//code executed only when client is connected
}
}
I’ve been told to use this function
void BLEServer::updateConnParams(esp_bd_addr_t remote_bda, uint16_t minInterval, uint16_t maxInterval, uint16_t latency, uint16_t timeout)
{
esp_ble_conn_update_params_t conn_params;
memcpy(conn_params.bda, remote_bda, sizeof(esp_bd_addr_t));
conn_params.min_int = minInterval;
conn_params.max_int = maxInterval;
conn_params.latency = latency;
conn_params.timeout = timeout;
esp_ble_gap_update_conn_params(&conn_params);
}
When I do I get this error
multiple definition of `BLEServer::updateConnParams(unsigned char*, unsigned short, unsigned short, unsigned short, unsigned short)'
BLE_Server.ino:31: first defined here
Is it possible you redeclared the function in your code? It’s already a part of the BLEServer library.
We miss a lot of code, but just call the BLEServer::updateConnParams after you made your connection and define the parameters you need. The min/max interval can be the same, or just use the interval which suites you, and make sure max interval * 1.25 ms * latency (max missed calls before connection would be defined as lost) is not greater than the timeout (value * 10 ms)

ESP32 Arduino BLE DeepSleep

I am working on a project involving 2 ESP32 Wemos D1 Mini boards. I am using the BLE feature to transmit a sensor reading from the "server" to the "client". I use a Characteristic Notify to the client which receives the sensor reading. If I want to implement deep sleep functionality to the server, what would happen to the client? Does the client also have to reset at some point?
Also, is it advisable to use Characteristic.Notify in a deep sleep scenario?
Thanks.
Server code:
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
#include "DHT.h"
#define DHTPIN 4
#define DHTTYPE DHT22
#define uS_TO_S_FACTOR 1000000 //Conversion factor for micro seconds to seconds
#define TIME_TO_SLEEP 15 //Time ESP32 will go to sleep (in seconds)
RTC_DATA_ATTR int bootCount = 0;
DHT dht(DHTPIN, DHTTYPE);
BLECharacteristic *pCharacteristic;
bool deviceConnected = false;
uint8_t txValue = 50;
#define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID
#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
deviceConnected = true;
};
void onDisconnect(BLEServer* pServer) {
deviceConnected = false;
}
};
//Function that prints the reason by which ESP32 has been awaken from sleep
void print_wakeup_reason(){
esp_sleep_wakeup_cause_t wakeup_reason;
wakeup_reason = esp_sleep_get_wakeup_cause();
switch(wakeup_reason)
{
case 1 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
case 2 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
case 3 : Serial.println("Wakeup caused by timer"); break;
case 4 : Serial.println("Wakeup caused by touchpad"); break;
case 5 : Serial.println("Wakeup caused by ULP program"); break;
default : Serial.println("Wakeup was not caused by deep sleep"); break;
}
}
void setup() {
Serial.begin(115200);
Serial.println(F("initating DHT22..."));
dht.begin();
// Create the BLE Device
BLEDevice::init("UART"); // Name must not be longer than 5 chars!!!
// Create the BLE Server
BLEServer *pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
// Create the BLE Service
BLEService *pService = pServer->createService(SERVICE_UUID);
// Create a BLE Characteristic
pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID_TX,
BLECharacteristic::PROPERTY_NOTIFY|BLECharacteristic::PROPERTY_READ|BLECharacteristic::PROPERTY_WRITE
);
BLE2902 *desc = new BLE2902();
desc->setNotifications(true);
pCharacteristic->addDescriptor(desc);
// Start the service
pService->start();
pServer->getAdvertising()->addServiceUUID(SERVICE_UUID);
// Start advertising
pServer->getAdvertising()->start();
Serial.println(pService->getUUID().toString().c_str());
Serial.println("Waiting a client connection to notify...");
if (deviceConnected) {
float f = dht.readTemperature(true);
char fStr[10];
sprintf(fStr, "%4.4f", f);
Serial.print("Temperature reading: ");
Serial.println(fStr);
Serial.printf("*** Sent Value: %d ***\n", fStr);
pCharacteristic->setValue(fStr);
pCharacteristic->notify();
//Set timer to 5 seconds
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
Serial.println("Setup ESP32 to sleep for every " + String(TIME_TO_SLEEP) +
" Seconds");
//Go to sleep now
esp_deep_sleep_start();
}
//delay(60000);
}
void loop() {}
Client code:
#include "BLEDevice.h"
#include <WiFi.h>
// The remote service we wish to connect to.
static BLEUUID serviceUUID("6E400001-B5A3-F393-E0A9-E50E24DCCA9E");
static BLEUUID charUUID("6E400003-B5A3-F393-E0A9-E50E24DCCA9E");
static BLEAddress *pServerAddress;
static boolean doConnect = false;
static boolean connected = false;
static BLERemoteCharacteristic* pRemoteCharacteristic;
const char* ssid = "Kings";
const char* password = "GoCanada";
const char* host = "menezes-service.herokuapp.com";
WiFiClient client;
static void notifyCallback(
BLERemoteCharacteristic* pBLERemoteCharacteristic,
uint8_t* pData,
size_t length,
bool isNotify) {
Serial.print(pBLERemoteCharacteristic->getUUID().toString().c_str());
Serial.print(" of data length ");
Serial.println(length);
//std::string value = pBLERemoteCharacteristic->readValue();
byte buffer[42];
Serial.print("The characteristic value sent was: ");
//Serial.println(pBLERemoteCharacteristic->readValue().c_str());
//Serial.println(pBLERemoteCharacteristic->readUInt8());
std::string farhenheight = pRemoteCharacteristic->readValue();
Serial.print("Farheinheight: ");
Serial.println(farhenheight.c_str());
Serial.println(F("Posting to api!"));
Serial.println();
Serial.println("closing connection");
}
class MyClientCallback : public BLEClientCallbacks {
void onConnect(BLEClient* pclient) {
Serial.println("connected again ... ");
}
void onDisconnect(BLEClient* pclient) {
connected = false;
Serial.println("onDisconnect");
}
};
bool connectToServer(BLEAddress pAddress) {
Serial.print("Forming a connection to ");
Serial.println(pAddress.toString().c_str());
BLEClient* pClient = BLEDevice::createClient();
Serial.println(" - Created client");
pClient->setClientCallbacks(new MyClientCallback());
// Connect to the remove BLE Server.
pClient->connect(pAddress);
Serial.println(" - Connected to server");
// Obtain a reference to the service we are after in the remote BLE server.
BLERemoteService* pRemoteService = pClient->getService(serviceUUID);
Serial.println(pRemoteService->toString().c_str());
if (pRemoteService == nullptr) {
Serial.print("Failed to find our service UUID: ");
Serial.println(serviceUUID.toString().c_str());
return false;
}
Serial.println(" - Found our service");
// Obtain a reference to the characteristic in the service of the remote BLE server.
pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID);
if (pRemoteCharacteristic == nullptr) {
Serial.print("Failed to find our characteristic UUID: ");
Serial.println(charUUID.toString().c_str());
return false;
}
Serial.println(" - Found our characteristic");
pRemoteCharacteristic->registerForNotify(notifyCallback);
}
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice) {
Serial.print("BLE Advertised Device found: ");
Serial.println(advertisedDevice.toString().c_str());
//Serial.print(advertisedDevice.haveServiceUUID());
if(advertisedDevice.haveServiceUUID()){
Serial.println(advertisedDevice.getServiceUUID().toString().c_str());
}
// We have found a device, let us now see if it contains the service we are looking for.
if (advertisedDevice.haveServiceUUID() && advertisedDevice.getServiceUUID().equals(serviceUUID)) {
//
Serial.print("Found our device! address: ");
advertisedDevice.getScan()->stop();
pServerAddress = new BLEAddress(advertisedDevice.getAddress());
doConnect = true;
} // Found our server
} // onResult
}; // MyAdvertisedDeviceCallbacks
void setup() {
Serial.begin(115200);
Serial.println("Starting Arduino BLE Client application...");
BLEDevice::init("");
BLEScan* pBLEScan = BLEDevice::getScan();
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(true);
pBLEScan->start(30);
} // End of setup.
// This is the Arduino main loop function.
void loop() {
if (doConnect == true) {
if (connectToServer(*pServerAddress)) {
Serial.println("We are now connected to the BLE Server.");
connected = true;
} else {
Serial.println("We have failed to connect to the server; there is nothin more we will do.");
}
//doConnect = false;
}
if (connected == false){
BLEDevice::getScan()->start(0);
}
else{
doConnect = false;
}
delay(1000); // Delay a second between loops.
} // End of loop
Please see answers to your questions below:-
If I want to implement deep sleep functionality to the server, what would happen to the client? Does the client also have to reset at some point?
No the client does not have to reset, but you may have to reconnect to the server because in deep sleep the BLE connection is lost. If you want the connection to be established automatically as soon as the server wakes up, then you have to update the client code so that it continuously attempts to reconnect to the server. This way, as soon as the server wakes up, the client would connect to it and continue receiving notifications.
Also, is it advisable to use Characteristic.Notify in a deep sleep scenario?
In deep sleep the CPU will be off, therefore you will not be able to send notifications in this state. In this mode you will only be able to wake up the CPU through a timer or an external peripheral (e.g. touch pins). Please see the link below for more information:-
https://lastminuteengineers.com/esp32-deep-sleep-wakeup-sources/
https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/sleep_modes.html
https://randomnerdtutorials.com/esp32-deep-sleep-arduino-ide-wake-up-sources/
I hope this helps.

Arduino SigFox temperature data Problems

Can someone help me with this Sigfox setup?
What have I done wrong? :-)
The only thing I wanted to achieve was to post the internal temperature and the status to the sigfox backend.
Each 15min, the data would be posted.
A configured an email from the service showing the temperature in degrees Celcius.
Posting to the backend is working.
However the email message and the data seems not to correspond.
When running the code in debug mode. The temperature is showing correctly in degrees Celcius.
Is there a manual available?
Code Arduino MKR FOX 1200
Temp.ino
#include <ArduinoLowPower.h>
#include <SigFox.h>
#include "conversions.h"
// Set oneshot to false to trigger continuous mode when you finisched setting up the whole flow
int oneshot = false;
#define STATUS_OK 0
/*
ATTENTION - the structure we are going to send MUST
be declared "packed" otherwise we'll get padding mismatch
on the sent data - see http://www.catb.org/esr/structure-packing/#_structure_alignment_and_padding
for more details
*/
typedef struct __attribute__ ((packed)) sigfox_message {
int16_t moduleTemperature;
uint8_t lastMessageStatus;
} SigfoxMessage;
// stub for message which will be sent
SigfoxMessage msg;
void setup() {
if (oneshot == true) {
// Wait for the serial
Serial.begin(115200);
while (!Serial) {}
}
if (!SigFox.begin()) {
// Something is really wrong, try rebooting
// Reboot is useful if we are powering the board using an unreliable power source
// (eg. solar panels or other energy harvesting methods)
reboot();
}
//Send module to standby until we need to send a message
SigFox.end();
if (oneshot == true) {
// Enable debug prints and LED indication if we are testing
SigFox.debug();
}
}
void loop() {
// Every 15 minutes, read all the sensor and send the data
// Let's try to optimize the data format
// Only use floats as intermediate representaion, don't send them directly
//sensors_event_t event;
// Start the module
SigFox.begin();
// Wait at least 30ms after first configuration (100ms before)
delay(100);
// We can only read the module temperature before SigFox.end()
float temperature = SigFox.internalTemperature();
msg.moduleTemperature = convertoFloatToInt16(temperature, 60, -60);
if (oneshot == true) {
Serial.println("Internal temp: " + String(temperature));
}
// Clears all pending interrupts
SigFox.status();
delay(1);
SigFox.beginPacket();
SigFox.write((uint8_t*)&msg, 12);
msg.lastMessageStatus = SigFox.endPacket();
if (oneshot == true) {
Serial.println("Status: " + String(msg.lastMessageStatus));
}
SigFox.end();
if (oneshot == true) {
// spin forever, so we can test that the backend is behaving correctly
while (1) {}
}
//Sleep for 15 minutes
LowPower.sleep(1 * 60 * 1000);
}
void reboot() {
NVIC_SystemReset();
while (1);
}
Conversion.h
#define UINT16_t_MAX 65536
#define INT16_t_MAX UINT16_t_MAX/2
int16_t convertoFloatToInt16(float value, long max, long min) {
float conversionFactor = (float) (INT16_t_MAX) / (float)(max - min);
return (int16_t)(value * conversionFactor);
}
uint16_t convertoFloatToUInt16(float value, long max, long min = 0) {
float conversionFactor = (float) (UINT16_t_MAX) / (float)(max - min);
return (uint16_t)(value * conversionFactor);
}
Settings Sigfox Backend - email Callbacks
With the current convertoFloatToInt16, it will not be possible to display the real temperature in an email directly from Sigfox Backend.
You either need to use a callback from Sigfox Backend to a server that implements convertoFloatToUInt16 and then sends the email, or send the temperature in a format that the Sigfox Backend can decode natively (32-bit float is probably the most suitable).

How to turn on and off LEDs by Raspberry Pi IoT connected to Arduino with I2C on an UWP project?

I have an Arduino Uno and a Raspberry Pi 3 with Windows IoT Core. I've tried to use this method to pass some info to my Arduino, like telling it to initiate a pin or getting and parsing a string. This method works perfectly for getting info from the Arduino (like sensor parameters).
I was able to send a byte to the Arduino and make an action inside my Arduino code, based on the byte sent (like init pin 7 when getting the number 2). BUT it only works once. I have to reset the Arduino so it would accept bytes from the Raspberry Pi again (I can turn on a LED connected to Arduino from my Raspberry Pi but can't turn it of. The reverse is also true.
My goal is to create a web site inside the Raspberry Pi for controlling things. But to start I'm using UWP. I'm trying to pass data from IoT Core running on a Raspberry Pi 3 to an Arduino Uno (not the reverse) or manage and control Arduino Uno pins with an I2C connection.
My MainPage.xaml:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using Windows.Devices.I2c;
using System.Threading.Tasks;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
namespace I2CComm {
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page {
private I2cDevice arduio; // Used to Connect to Arduino
private DispatcherTimer timer = new DispatcherTimer();
public MainPage() {
this.InitializeComponent();
Initialiasecom();
}
public async void Initialiasecom() {
var settings = new I2cConnectionSettings(0x40);
// Slave Address of Arduino Uno
settings.BusSpeed = I2cBusSpeed.FastMode;
// this bus has 400Khz speed
string aqs = I2cDevice.GetDeviceSelector("I2C1");
// This will return Advanced Query String which is used to select i2c device
var dis = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(aqs);
arduio = await I2cDevice.FromIdAsync(dis[0].Id, settings);
timer.Tick += Timer_Tick;
// We will create an event handler
timer.Interval = new TimeSpan(0,0,0,0,500);
// Timer_Tick is executed every 500 milli second
timer.Start();
}
private async void Timer_Tick(object sender, object e) {
byte[] response = new byte[2];
try {
arduio.Read(response);
// this function will read data from Arduino
}
catch (Exception p) {
Windows.UI.Popups.MessageDialog msg = new Windows.UI.Popups.MessageDialog(p.Message);
await msg.ShowAsync();
// this will show error message(if any)
}
}
private void TurnOn_Click(object sender, RoutedEventArgs e) {
try {
byte[] sendpos;
sendpos = BitConverter.GetBytes(2);
arduio.Write(sendpos);
}
catch (Exception p) {
Windows.UI.Popups.MessageDialog msg = new Windows.UI.Popups.MessageDialog(p.Message);
}
}
private void TurnOff_Click(object sender, RoutedEventArgs e) {
try {
byte[] sendpos;
sendpos = BitConverter.GetBytes(1);
arduio.Write(sendpos);
}
catch (Exception p) {
Windows.UI.Popups.MessageDialog msg = new Windows.UI.Popups.MessageDialog(p.Message);
}
}
}
}
My Arduino code is:
#include <Wire.h>
// Library that contains functions to have I2C Communication
#define SLAVE_ADDRESS 0x40
// Define the I2C address to Communicate to Uno
byte response[2]; // this data is sent to PI
volatile short LDR_value; // Global Declaration
const int LDR_pin=A0; //pin to which LDR is connected A0 is analog A0 pin
const int ledPin = 7;
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
Wire.begin(SLAVE_ADDRESS);
// this will begin I2C Connection with 0x40 address
Wire.onRequest(sendData);
// sendData is a function called when Pi requests data
Wire.onReceive(I2CReceived);
pinMode(LDR_pin,INPUT);
digitalWrite(ledPin, HIGH);
}
void loop() {
delay(500);
}
void I2CReceived(int NumberOfBytes) {
/* WinIoT have sent data byte; read it */
byte ReceivedData = Wire.read();
Serial.println(ReceivedData);
if (ReceivedData == 2) {
digitalWrite(ledPin, HIGH);
return;
} else if (ReceivedData == 1) {
digitalWrite(ledPin, LOW);
return;
}
}
void sendData() {
LDR_value=analogRead(LDR_pin);
// Arduino returns 10-bit data but we need to convert it to 8 bits
LDR_value=map(LDR_value,0,1023,0,255);
response[0]=(byte)LDR_value;
Wire.write(response,2); // return data to PI
}
Raspberry Pi send 4 bytes(2 is Int) instead of 1 byte. You need receive all of the bytes in Arduino. You can do it like this:
void I2CReceived(int NumberOfBytes) {
/* WinIoT have sent data byte; read it */
byte ReceivedData = Wire.read();
Serial.println(ReceivedData);
while (0 < Wire.available()) {
byte UselessData = Wire.read();
Serial.println(UselessData);
}
if (ReceivedData == 2) {
digitalWrite(ledPin, HIGH);
return;
} else if (ReceivedData == 1) {
digitalWrite(ledPin, LOW);
return;
}
}

Unstable or slow communication between ESP8266 server and web browser client

I am using an ESP8266 Thing Dev board configured as an access point and server to store data from temperature sensors.
The goal is to access this data with an Android application, but for now, the client used is my computer running Chrome.
The sensors provide new temperatures every 250 ms, which are added to a string (JSON formatted).
When the client requests the data, the string is ended (closing JSON structure), and printed on the server.
The client should be able to access up to 2*50 values at a time. However, each time a request is send, either only 2 or 4 values are printed, either the page is not working.
My Arduino code, using ESP8266 and TMP102 libraries for arduino :
#include <ESP8266WiFi.h>
#include <Wire.h>
#include <Ticker.h>
#include "tmp102.h"
#define NB_MAX_TEMP 50
#define MAX_INPUT 20
const byte sensorAddress1 = 0x90; // ADD0 -> GND
const byte sensorAddress2 = 0x92; // ADD0 -> V+
tmp102 *thermometer1 = new tmp102(&Wire);
tmp102 *thermometer2 = new tmp102(&Wire);
// Timer
Ticker ticker;
bool flag = false;
// Wifi
const char WiFiAPPSK[] = "sparkfun"; // Wifi password
WiFiServer server(80);
int count = 0;
String s;
void setupWiFi()
{
WiFi.mode(WIFI_AP);
// Do a little work to get a unique-ish name. Append the
// last two bytes of the MAC (HEX'd) to "ThingDev-":
uint8_t mac[WL_MAC_ADDR_LENGTH];
WiFi.softAPmacAddress(mac);
String macID = String(mac[WL_MAC_ADDR_LENGTH - 2], HEX) +
String(mac[WL_MAC_ADDR_LENGTH - 1], HEX);
macID.toUpperCase();
String AP_NameString = "ThingDev-" + macID;
char AP_NameChar[AP_NameString.length() + 1];
memset(AP_NameChar, 0, AP_NameString.length() + 1);
for (int i = 0; i < AP_NameString.length(); i++)
AP_NameChar[i] = AP_NameString.charAt(i);
WiFi.softAP(AP_NameChar, WiFiAPPSK);
}
void timer_done()
{
flag = true;
}
void acquire()
{
int temp1 = 0, temp2 = 0;
if (thermometer1->readTemp(temp1))
{
// If we're reading pins, print out those values:
// first temp
s += String(temp1 * 0.0625);
}
s += ",";
if (thermometer2->readTemp(temp2))
{
// If we're reading pins, print out those values:
// second temp
s += String(temp2 * 0.0625);
}
return;
}
void setup()
{
Wire.begin(); // start the I2C library
Serial.begin(115200);
thermometer1->init(sensorAddress1);
thermometer2->init(sensorAddress2);
//Set default config.
thermometer1->writeConf(TMP102_DEFAULT_CONF);
thermometer2->writeConf(TMP102_DEFAULT_CONF);
setupWiFi();
server.begin();
// timer every 0.25s
ticker.attach(0.25, timer_done);
}
void loop()
{
// Check if a client has connected
WiFiClient client = server.available();
if (!client) {
return;
}
if (flag) {
flag = false;
int temp1 = 0, temp2 = 0;
if (count == 0) {
// prepare string
s = "HTTP/1.1 200 OK\r\n";
s += "Content-Type: text/html\r\n\r\n";
s += "{temp:[";
}
delay(1);
// add a measurement
s += "[";
acquire();
s += "],";
count += 1;
if (count == NB_MAX_TEMP) {
// Prevent the string to become infinite
count = 0;
s = s.substring(0, s.length() - 1);
s += "]};";
}
}
if (client.available() > 0) {
// Read the first line of the request
String req = client.readStringUntil('\r');
client.flush();
Serial.println(req);
if (req.indexOf("/read") != -1) {
// End the string
s.setCharAt(s.length() - 1, '\0');
s += "]};";
client.print(s);
Serial.println(s);
count = 0;
}
}
delay(1);
Serial.println("Client disconnected");
// The client will actually be disconnected
// when the function returns and 'client' object is detroyed
}
And a sample of what I get on the Serial console (the JSON string is the same I read on the server page) :
GET /read HTTP/1.1
HTTP/1.1 200 OK
Content-Type: text/html
{temp:[[24.00,24.56],[24.00,24.56];
Client disconnected
GET /favicon.ico HTTP/1.1
Client disconnected
GET /read HTTP/1.1
HTTP/1.1 200 OK
Content-Type: text/html
{temp:[[24.00,24.56];
Client disconnected
What am I doing wrong ? Am I using a blocking function ? Are the /favicon.ico requests causing trouble ?
For information, the access point part, and the sensor part of my code have been tested separately and work as expected.
Thanks in advance.

Resources