How to switch between bluetooth and wifi in esp32 - http

I am doing an autonomous car project, I need manual control as well as an autonomous function, so the manual control is done through wif using "gesture control" and for the autonomous control I want to send the location data via Bluetooth, I will be choosing between both, using a toggle switch connected to ground and one of the pins. I went through the inbuilt wifi Bluetooth switch program but I have no idea how to modify it. I am still okay if I can send data through the HTTP request but, then I have to connect it to a network right? But again I don't have any idea, how to write the code to switch between the two networks.I am using an ESP32 devkit
This is the inbuilt example code for Bluetooth switch
#include "WiFi.h"
#define STA_SSID "your-ssid"
#define STA_PASS "your-pass"
#define AP_SSID "esp32"
enum { STEP_BTON, STEP_BTOFF, STEP_STA, STEP_AP, STEP_AP_STA, STEP_OFF, STEP_BT_STA, STEP_END };
void onButton(){
static uint32_t step = STEP_BTON;
switch(step){
case STEP_BTON://BT Only
Serial.println("** Starting BT");
btStart();
break;
case STEP_BTOFF://All Off
Serial.println("** Stopping BT");
btStop();
break;
case STEP_STA://STA Only
Serial.println("** Starting STA");
WiFi.begin(STA_SSID, STA_PASS);
break;
case STEP_AP://AP Only
Serial.println("** Stopping STA");
WiFi.mode(WIFI_AP);
Serial.println("** Starting AP");
WiFi.softAP(AP_SSID);
break;
case STEP_AP_STA://AP+STA
Serial.println("** Starting STA");
WiFi.begin(STA_SSID, STA_PASS);
break;
case STEP_OFF://All Off
Serial.println("** Stopping WiFi");
WiFi.mode(WIFI_OFF);
break;
case STEP_BT_STA://BT+STA
Serial.println("** Starting STA+BT");
WiFi.begin(STA_SSID, STA_PASS);
btStart();
break;
case STEP_END://All Off
Serial.println("** Stopping WiFi+BT");
WiFi.mode(WIFI_OFF);
btStop();
break;
default:
break;
}
if(step == STEP_END){
step = STEP_BTON;
} else {
step++;
}
//little debounce
delay(100);
}
void WiFiEvent(WiFiEvent_t event){
switch(event) {
case SYSTEM_EVENT_AP_START:
Serial.println("AP Started");
WiFi.softAPsetHostname(AP_SSID);
break;
case SYSTEM_EVENT_AP_STOP:
Serial.println("AP Stopped");
break;
case SYSTEM_EVENT_STA_START:
Serial.println("STA Started");
WiFi.setHostname(AP_SSID);
break;
case SYSTEM_EVENT_STA_CONNECTED:
Serial.println("STA Connected");
WiFi.enableIpV6();
break;
case SYSTEM_EVENT_AP_STA_GOT_IP6:
Serial.print("STA IPv6: ");
Serial.println(WiFi.localIPv6());
break;
case SYSTEM_EVENT_STA_GOT_IP:
Serial.print("STA IPv4: ");
Serial.println(WiFi.localIP());
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
Serial.println("STA Disconnected");
break;
case SYSTEM_EVENT_STA_STOP:
Serial.println("STA Stopped");
break;
default:
break;
}
}
void setup() {
Serial.begin(115200);
pinMode(0, INPUT_PULLUP);
WiFi.onEvent(WiFiEvent);
Serial.print("ESP32 SDK: ");
Serial.println(ESP.getSdkVersion());
Serial.println("Press the button to select the next mode");
}
void loop() {
static uint8_t lastPinState = 1;
uint8_t pinState = digitalRead(0);
if(!pinState && lastPinState){
onButton();
}
lastPinState = pinState;
}
Below is part of the main code i use, i want to modify it so i can either switch between bluetooth and esp now or between espnow and http
*/
#include <esp_now.h>
#include <WiFi.h>
#include <esp_wifi.h>
#include <TinyGPS++.h> // Tiny GPS Plus Library
#define CHANNEL 4
uint8_t mac[] = {0x36, 0x33, 0x33, 0x33, 0x33, 0x33};
struct __attribute__((packed)) DataStruct {
//char text[32];
int x;
int y;
unsigned long time;
};
DataStruct myData;
//*****************************************************************************************************
// GPS Locations
unsigned long Distance_To_Home; // variable for storing the distance to destination
int ac =0; // GPS array counter
int wpCount = 0; // GPS waypoint counter
double Home_LATarray[50]; // variable for storing the destination Latitude - Only Programmed for 5 waypoint
double Home_LONarray[50]; // variable for storing the destination Longitude - up to 50 waypoints
int increment = 0;
#define autopilot 13
void gesturecontroll();
void getGPS();
void getCompass();
void setWaypoint();
void move();
int blueToothVal;
void setup()
{ Serial.begin(9600); // Serial 0 is for communication with the computer
S2.begin(9600); // Serial 2 is for GPS communication at 9600 baud - DO NOT MODIFY - Ublox Neo 6m
Serial.println("ESPNow/Basic/Slave Example");
//Set device in AP mode to begin with
WiFi.mode(WIFI_AP);
// configure device AP mode
// This is the mac address of the Slave in AP Mode
esp_wifi_set_mac(ESP_IF_WIFI_STA, &mac[0]);
Serial.print("AP MAC: "); Serial.println(WiFi.softAPmacAddress());
// Init ESPNow with a fallback logic
if (esp_now_init()!=0) {
Serial.println("*** ESP_Now init failed");
while(true) {};
}
// Once ESPNow is successfully Init, we will register for recv CB to
// get recv packer info.
esp_now_register_recv_cb(OnDataRecv);
Serial.print("Aheloiioi");
// Extras////////////////////////////////////////////////////////////////////////////////////
pinMode(autopilot, INPUT);
}
void OnDataRecv(const uint8_t *mac_addr, const uint8_t *data, int data_len) {
memcpy(&myData, data, sizeof(myData));
char macStr[18];
snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
Serial.print("Last Packet Recv from: "); Serial.println(macStr);
Serial.print("Last Packet Recv Data: ");
Serial.println(myData.x);
Serial.println(myData.y);
Serial.println("");
Serial.println();
//move();
Serial.println();
}
//********************************************************************************************************
// Main Loop
void loop()
{ if (autopilot == HIGH)
{
move(); // going for manual control
}
else
{
getGPS(); // Update the GPS location
getCompass(); // Update the CompaSerial Heading
Ping(); // Use at your own discretion, this is not fully tested
}
}
I could have tried if all these initial setups came under an "if statement" in the void loop, but these initial setups come in the void setup,so i have no idea on how to proced

I think this example need hardware also like toggle switch between GPIO 0 & ground on top of the code these comments are there.
//Sketch shows how to switch between Wi-Fi and Bluetooth or use both
// Button is attached between GPIO 0 and GND and modes are switched with each press
this example code as wifi.h library included but "BluetoothSerial.h" library is not included I don't it works properly in real time without this "BluetoothSerial.h" library
About terminology in ESP32 Wi-Fi go through it:- https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_wifi.html
I think first prepare hardware as given in example then start coding.

Related

Could not find a valid MPU6050 sensor

I am using the below code with arduino-uno, but often getting "Could not find a valid MPU6050 sensor
#include <Wire.h>
#include <MPU6050.h>
MPU6050 mpu;
void setup() {
Serial.begin(115200);
Serial.println("Initialize MPU6050");
while (!mpu.begin()) {
Serial.println("Could not find a valid MPU6050 sensor, check wiring!");
delay(500);
}
}
void loop() {
}
My Arduino is working fine,
So, I checked MPU6050 using below code,
#include <Wire.h>
void setup()
{
Wire.begin();
Serial.begin(115200);
while (!Serial); // Leonardo: wait for serial monitor
Serial.println("\nI2C Scanner");
}
void loop()
{
byte error, address;
int nDevices;
Serial.println("Scanning...");
nDevices = 0;
for(address = 1; address < 127; address++ )
{
// The i2c_scanner uses the return value of
// the Write.endTransmisstion to see if
// a device did acknowledge to the address.
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0)
{
Serial.print("I2C device found at address 0x");
if (address<16)
Serial.print("0");
Serial.print(address,HEX);
Serial.println(" !");
nDevices++;
}
else if (error==4)
{
Serial.print("Unknown error at address 0x");
if (address<16)
Serial.print("0");
Serial.println(address,HEX);
}
}
if (nDevices == 0)
Serial.println("No I2C devices found\n");
else
Serial.println("done\n");
delay(5000); // wait 5 seconds for next scan
}
Got Output as expected
Scanning...
I2C device found at address 0x68 !
done
From the above output I hope GPU6050 is working
How can I get values from GPU6050?
Your code is working as expected, it tells you in setup() when it can't connect to the device, until it can.
So when it stops printing the message, it is connected.
Now in loop() you should write your code to negotiate with the device.
Here's an excellent place to start with.

How can I create an automated GPS tracker using A9G AI Thinker module?

I have an AI Thinker A9G module connected to an ESP8266 D1 mini. I have the following script to send and receive AT commands to/from the module. The idea is to get a SMS with the Google maps GPS location of the module onto my mobile phone.
// GPS tracker with AI Thinker A9G module and AZ Delivery D1 Mini ESP8266 module
#include <SoftwareSerial.h>
#define rxPin D7
#define txPin D8
SoftwareSerial A9modem(rxPin, txPin); // Pins D7 Rx and D8 Tx are used as used as software serial pins
String incomingData; // For storing incoming serial data
String gpsData; // For storing location data
char msg;
char call;
void setup()
{
Serial.begin(115200); // Baud rate for serial monitor
A9modem.begin(115200); // Baud rate for GSM shield
Serial.println("GPS/GSM A9G BEGIN");
Serial.println("Enter character for control option: ");
Serial.println("h : to disconnect a call");
Serial.println("s : to send a message");
Serial.println("r : to receive a message");
Serial.println("c : to make a call");
Serial.println("l : to read location");
Serial.println("d : to disconnect gps");
Serial.println();
delay(100);
// Set SMS mode to text mode
A9modem.print("AT+CMGF=1\r");
delay(100);
// Set GSM module to TP show the output on serial out
A9modem.print("AT+CNMI=2,2,0,0,0\r");
delay(100);
}
void loop()
{
ReceiveMessage();
gpsData = incomingData.substring(33, 52);
Serial.print("Location: ");
Serial.println(gpsData);
delay(2000);
if (Serial.available() > 0)
switch(Serial.read())
{
case 's':
SendMessage();
break;
case 'r':
ReceiveMessage();
break;
case 'c':
MakeCall();
break;
case 'h':
HangupCall();
break;
case 'l':
ReadLocation();
break;
case 'd':
DisconnectGps();
break;
}
}
void ReceiveMessage()
{
if (A9modem.available() > 0)
{
incomingData = A9modem.readString(); // Get the data from the serial port
Serial.print(incomingData);
delay(100);
}
}
void SendMessage()
{
A9modem.println("AT+CMGF=1"); // Sets the GSM Module into text mode
delay(1000); // Delay of one second
A9modem.println("AT+CMGS=\"xxxxxxxxxxxxx\"\r"); // Replace your mobile number here
delay(1000);
String sms = "http://maps.google.com/maps?q=" + gpsData; // Create the SMS location string
A9modem.println(sms);
delay(100);
A9modem.println((char)26); // ASCII code of CTRL+Z
delay(1000);
}
void MakeCall()
{
A9modem.println("ATD+xxxxxxxxxxxxx;"); // Replace your mobile number here
Serial.println("Calling "); // Print response over serial port
delay(1000);
}
void HangupCall()
{
A9modem.println("ATH");
Serial.println("Hangup Call");
delay(1000);
}
void DisconnectGps()
{
A9modem.println("AT+GPS=0");
Serial.println("Disconnect GPS");
delay(1000);
}
void ReadLocation()
{
A9modem.println("AT+GPS=1");
delay(1000);
A9modem.println("AT+LOCATION=2"); // Check location every two seconds
delay(2000);
}
So if I use the commands "l" and "s" in Arduino IDE serial monitor everything is working well but I don't know how to change the code in a way that I get a fully automated GPS tracker. The idea is the following: Power on starts the tracker. When gpsData string is not empty the first SMS will be send to my mobile phone. The next SMS follows 20 minutes later and so on until power is switched off. Could you help please?
Thanks in advance!
Finally I came up with this solution but I'm not very happy with it (it is working but I have to restart the module from time to time because there are no GPS data). There are 3 reasons for this: There is no error handling for the GPS function, I set the delays in a more ore less random way to get everything working but I don't know if the values make sense and I don't know if the substring() function is the best way to get the location from the serial response.
// GPS tracker with AI Thinker A9G module and AZ Delivery D1 Mini
ESP8266 module
#include <SoftwareSerial.h>
#define rxPin D7
#define txPin D8
SoftwareSerial A9modem(rxPin, txPin); // Pins D7 Rx and D8 Tx are used as used as software serial pins
String incomingData; // For storing incoming serial data
String gpsData; // For storing location data
int runGps = 1;
int sendSms = 0;
void setup()
{
pinMode(LED_BUILTIN, OUTPUT); // Use builtin LED for correct GPS status
Serial.begin(115200); // Baud rate for serial monitor
A9modem.begin(115200); // Baud rate for GSM shield
// Set SMS mode to text mode
A9modem.print("AT+CMGF=1\r");
delay(300);
// Set GSM module to TP show the output on serial out
A9modem.print("AT+CNMI=2,2,0,0,0\r");
delay(1000);
Serial.end();
delay(500);
}
void loop()
{
Serial.begin(115200);
ReceiveMessage(); // Start a new serial stream
gpsData = incomingData.substring(33, 52); // Strip all unnessesary data from the stream
Serial.print("Location: "); // Check if the location data are correct
Serial.println(gpsData);
delay(1000);
if(runGps == 1) { // Start GPS
ReadLocation();
delay(20000); // Wait for GPS to be ready
}
if(gpsData.length() == 19 && sendSms == 0) { // If the location string is correct send SMS
if (isdigit(gpsData.charAt(0))) { // Check if the stream starts with a number
SendMessage();
digitalWrite(LED_BUILTIN, HIGH);
delay(300);
digitalWrite(LED_BUILTIN, LOW);
delay(300);
digitalWrite(LED_BUILTIN, HIGH);
delay(300);
digitalWrite(LED_BUILTIN, LOW);
delay(300);
digitalWrite(LED_BUILTIN, HIGH);
}
}
if(runGps == 0 && sendSms == 1) {
runGps = 1;
sendSms = 0;
delay(6000); // Make sure that all SMS serial communication is over
while (A9modem.available()) {
A9modem.read(); // Delete all data from serial buffer
}
delay(300000); // If SMS was sent wait 5 minutes before running the main loop again
Serial.end();
delay(500);
}
}
void ReceiveMessage()
{
if (A9modem.available() > 0)
{
incomingData = A9modem.readString(); // Get the data from the serial port
Serial.print(incomingData);
delay(500);
}
}
void SendMessage()
{
sendSms = 1; // Stop starting the SendMessage function
A9modem.println("AT+CMGF=1"); // Sets the GSM Module into text mode
delay(1000);
A9modem.println("AT+CMGS=\"xxxxxxxxxx\"\r"); // Replace your mobile number here
delay(1000);
String sms = "http://maps.google.com/maps?q=" + gpsData; // Create the SMS string
A9modem.println(sms);
delay(500);
A9modem.println((char)26); // ASCII code of CTRL+Z
delay(500);
}
void ReadLocation()
{
runGps = 0; // Stop starting the ReadLocation function
A9modem.println("AT+GPS=1");
delay(1000);
A9modem.println("AT+LOCATION=2"); // Check location every two seconds
delay(2000);
}
Try turning ON the NMEA stream from the A9G. Say you want to get the NMEA data every t seconds, you can add and then call the following function once in the void setup()
void TurnOnNMEA(int t)
{
if(t > 3600)
t = 3600; // Because the max time is 3600s
A9modem.print("AT+GPSRD=");
A9modem.println(t);
while(!A9modem.available()); // wait till the A9G sends a response
char c;
while(A9modem.available())
{
c = A9modem.read();
Serial.print(c);
delay(2); // Time needed for the next character
}
}
This will start the NMEA data stream every t seconds which you can print using the following function,
void ReadNMEA()
{
char c; // Read each character from the stream as it comes
if(A9modem.available())
{
c = A9modem.read();
Serial.print(c);
delay(2); // Time needed for the next character
}
}
Parsing and decoding the NMEA is a bit tricky thing to do. There is a lot of information inside it and the decoding depends on what you want to do with it. If you just want the location, you can parse the $GNGGA line.
When parsing the data, DO NOT USE Arduino String() class. It is a very bad idea when handling this kind of stream. Instead, use char array.

vw_get_message return false when running motors

I am using Arduino for the first time, my project consists of RF transmitter connected with arduino UNO and a RF receiver connected to Arduino Mega.
I'm try to send data from transmitter and print it on receiver serial using VirtualWire library and every thing is okey for this receiver code:
#include <VirtualWire.h>
int x=9;
int y=8;
int z=10;
int r=7;
void setup()
{
Serial.begin(9600);
pinMode(x,OUTPUT);
pinMode(y,OUTPUT);
pinMode(z,OUTPUT);
pinMode(r,OUTPUT);
vw_setup(2000);
vw_rx_start();
}
void loop()
{
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
if (vw_get_message(buf, &buflen)) // Non-blocking
{
int i;
// Message with a good checksum received, print it.
Serial.print("Got: ");
for (i = 0; i < buflen; i++)
{
Serial.print(buf[i], HEX);
Serial.print(' ');
}
Serial.println();
}
}
Then i add some if statments to run 2 motors (connected to x,y,z,r pins) based on recrived values :
#include <VirtualWire.h>
int x=9;
int y=8;
int z=10;
int r=7;
void setup()
{
Serial.begin(9600);
pinMode(x,OUTPUT);
pinMode(y,OUTPUT);
pinMode(z,OUTPUT);
pinMode(r,OUTPUT);
vw_setup(2000);
vw_rx_start();
}
void loop()
{
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
if (vw_get_message(buf, &buflen)) // Non-blocking
{
int i;
// Message with a good checksum received, print it.
Serial.print("Got: ");
for (i = 0; i < buflen; i++)
{
if (buf[i]==0x77)//Stop motors
{
digitalWrite(x,LOW);
digitalWrite(y,LOW);
digitalWrite(z,LOW);
digitalWrite(r,LOW);
}
else
{
if(buf[i]==0x80)//2 motors clockwise
{
digitalWrite(x,LOW);
digitalWrite(y,HIGH);
digitalWrite(z,HIGH);
digitalWrite(r,LOW);
}
if (buf[i]==0x90)//counter clockwise
{
digitalWrite(x,HIGH);
digitalWrite(y,LOW);
digitalWrite(z,LOW);
digitalWrite(r,HIGH);
}
}
}
Now the problem is that when motors is stop working and I am sending the values that will run it either with or counterclockwise the motor works in the right direction but then does not respond to any data sent.
In short, when the motor stops working and I send data, the receiver receives the values and runs the motor violin is required, but then for example if the motor was working clockwise and sent the order which is running counterclockwise or even stop work, it does not respond and continues to move It was.
I noticed that this bacause when motors runs this function returns false
vw_get_message(buf, &buflen)
But i don't no why!
In VirtualWire library every time you send a new character or a set of characters your buffer will be overwritten. So the problem in this program is with your for loop checking. It will work fine if you just use the following
For example if you are sending characters like 'A', 'B' etc then
if (vw_get_message(buf, &buflen))
{
if(buf[0]=='A')
{
//move forward
}
if(buf[0]=='B')
{
//move backward
}
.... and so on
Hope this helps

Arduino-uno sketch not working properly after power gone

I'm relatively new to Arduino, and here are what I was trying to do.
I want to control a relay circuit using IR(InfarRet) remote. Here is the code what I'm using :
#include <IRremote.h>
int RECV_PIN = 6;
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
irrecv.enableIRIn();
pinMode (5 ,OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
if (irrecv.decode(&results)){
Serial.println(results.value,DEC);
irrecv.resume();
switch (results.value){
case 3150073167:
digitalWrite(5,HIGH);
break;
case 68850955:
digitalWrite (5,LOW);
break;
}
}
}
circuit is working properly,
but after power restart it is not working properly, hear is a snap :
Error :
how to fix this error ?
Usually, a controller is meant to run forever ("24/7").
In the rare case of a restart, the whole system should be set to a defined initial safe state. (That should usually be the same as during power off)
How come your relay remains ON while the arduino is OFF?
If you really want to store a previous state, EEPROM is a good place.
(Fully agree with KIIV)
RAM is volatile memory, and after power loss it is lost too (IO Ports are reset to INPUT mode without pull-ups).
You can use EEPROM to store last state and restore it in setup() function.
For AVR based arduinos something like this can be used:
#include <EEPROM.h>
#include <IRremote.h>
const int RELAY_PIN = 5;
const int RECV_PIN = 6;
const int address = 0;
byte state = 0;
decode_results results;
IRrecv irrecv(RECV_PIN);
void setup() {
Serial.begin(9600);
irrecv.enableIRIn();
state = EEPROM.read(address);
pinMode (RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, state);
}
void loop() {
if (irrecv.decode(&results)) {
Serial.println(results.value,DEC);
irrecv.resume();
switch (results.value){
case 3150073167LU:
if (state == LOW) {
state = HIGH;
EEPROM.write(address, state);
}
break;
case 68850955LU:
if (state == HIGH) {
state = LOW;
EEPROM.write(address, state);
}
break;
default:
break;
}
digitalWrite(RELAY_PIN, state);
}
}

DHT22 (sensor) to Pachube via Arduino with Ethernet shield error

I'm trying to connect a DHT22 sensor to the Pachube online service.
I am understanding the code and have everything wired up correctly but I get this error:
DHT22 Library Demo
Requesting data at 6335
Sync Timeout
What does sync timeout mean? Is is a network problem?
How could I fix this?
Here is my code anyway:
/* Feed temperature and humidity to Pachube.
Based on the following examples:
Sample code from nethoncho's DHT22 library:
https://github.com/nethoncho/Arduino-DHT22
Tom Igoe's PachubeClient:
http://arduino.cc/en/Tutorial/PachubeCient
*/
#include <DHT22.h>
#include <SPI.h>
#include <Ethernet.h>
// Data wire is plugged into port 7 on the Arduino
// Connect a 4.7K resistor between VCC and the data pin (strong pullup)
#define DHT22_PIN 2
// Setup a DHT22 instance
DHT22 myDHT22(DHT22_PIN);
static unsigned long lWaitMillis;
// assign a MAC address for the ethernet controller.
// fill in your address here:
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
// assign an IP address for the controller:
byte ip[] = {
192,168,0,30 };
byte gateway[] = {
192,168,1,2};
byte subnet[] = {
255, 255, 255, 0 };
// The address of the server you want to connect to (pachube.com):
byte server[] = {
173,203,98,29 };
// initialize the library instance:
Client client(server, 80);
boolean lastConnected = false; // state of the connection last time through the main loop
const long postingInterval = 180000; //delay between updates to Pachube.com
int backoff = 0;
void setup(void)
{
// start serial port
Serial.begin(9600);
Serial.println("DHT22 Library Demo");
// start the ethernet connection:
Ethernet.begin(mac, ip);
// give the ethernet module time to boot up:
delay(1000);
lWaitMillis = millis() + 5000;
}
void loop() {
// if there's incoming data from the net connection.
// send it out the serial port. This is for debugging
// purposes only:
if (client.available()) {
char c = client.read();
Serial.print(c);
}
// if there's no net connection, but there was one last time
// through the loop, then stop the client:
if (!client.connected() && lastConnected) {
Serial.println();
Serial.println("disconnecting.");
client.stop();
while(client.status() != 0) {
Serial.print("Client status: ");
Serial.println(client.status());
delay(5);
}
}
// if you're not connected, and ten seconds have passed since
// your last connection, then connect again and send data:
if(!client.connected() && (long)( millis() - lWaitMillis ) >= 0 ) {
if (readData()) {
int temp = myDHT22.getTemperatureC();
int humidity = myDHT22.getHumidity() + .5;
sendData(temp, humidity);
}
lWaitMillis += postingInterval;
if (lWaitMillis < millis()) {
lWaitMillis = millis() + postingInterval;
}
Serial.print("Next attempt at ");
Serial.println(lWaitMillis);
Serial.println();
}
// store the state of the connection for next time through
// the loop:
lastConnected = client.connected();
}
boolean readData()
{
DHT22_ERROR_t errorCode;
Serial.print("Requesting data at ");
Serial.println(millis());
errorCode = myDHT22.readData();
switch(errorCode)
{
case DHT_ERROR_NONE:
Serial.print("Got Data ");
Serial.print(myDHT22.getTemperatureC());
Serial.print("C ");
Serial.print(myDHT22.getHumidity());
Serial.println("%");
return true;
break;
case DHT_ERROR_CHECKSUM:
Serial.print("check sum error ");
Serial.print(myDHT22.getTemperatureC());
Serial.print("C ");
Serial.print(myDHT22.getHumidity());
Serial.println("%");
break;
case DHT_BUS_HUNG:
Serial.println("BUS Hung ");
break;
case DHT_ERROR_NOT_PRESENT:
Serial.println("Not Present ");
break;
case DHT_ERROR_ACK_TOO_LONG:
Serial.println("ACK time out ");
break;
case DHT_ERROR_SYNC_TIMEOUT:
Serial.println("Sync Timeout ");
break;
case DHT_ERROR_DATA_TIMEOUT:
Serial.println("Data Timeout ");
break;
case DHT_ERROR_TOOQUICK:
Serial.println("Polled too quick ");
break;
}
return false;
}
// this method makes a HTTP connection to the server:
void sendData(int temp, int humidity) {
// if there's a successful connection:
if (client.connect()) {
backoff = 0;
Serial.println("connecting...");
// send the HTTP PUT request.
// fill in your feed address here:
client.print("PUT /v2/feeds/36800.csv HTTP/1.1\n");
client.print("Host: api.pachube.com\n");
// fill in your Pachube API key here:
client.print("X-PachubeApiKey: a6714b6a217827edadfd003843c03c259a08add554eda3871b844612eddc6819\n");
client.print("Content-Length: ");
// calculate the length of the sensor reading in bytes:
int thisLength = 2 + getLength(temp) + 2 + 2 + getLength(humidity);
client.println(thisLength, DEC);
// last pieces of the HTTP PUT request:
client.print("Content-Type: text/csv\n");
client.println("Connection: close\n");
// here's the actual content of the PUT request:
client.print(0, DEC);
client.print(",");
client.println(temp, DEC);
client.print(1, DEC);
client.print(",");
client.println(humidity, DEC);
}
else {
// if you couldn't make a connection:
Serial.println("connection failed, resetting.");
Ethernet.begin(mac, ip);
delay(1000);
client.stop();
delay(1000);
}
}
// This method calculates the number of digits in the
// sensor reading. Since each digit of the ASCII decimal
// representation is a byte, the number of digits equals
// the number of bytes:
int getLength(int someValue) {
// there's at least one byte:
int digits = 1;
// continually divide the value by ten,
// adding one to the digit count for each
// time you divide, until you're at 0:
int dividend = someValue /10;
while (dividend > 0) {
dividend = dividend /10;
digits++;
}
// return the number of digits:
return digits;
}
You're running into DHT_ERROR_SYNC_TIMEOUT sensor error, that means that the DHT sensor is running into some sync problem, I guess.
What arduino are you using? Is your board's frequence 8 or 16Mhz?
Give a try to the edit described here, too. If it still doesn't work, I would try using sensor itself (i.e. without connecting to patchube) with some test sketch you can easily find for DHT22, just to make sure the sensor is working properly.
I had similar problem when using Arduino Nano v3.0 + ENC28J60 Ethernet shield. I tried to connect RF receiver to digital PIN #2 but this never worked.
Then I used different pin for the RF module (PIN #4 in my case) and everything worked fine.

Resources