How can I get accurate value of temperature and humidity from DHT11 and ESP8266 - arduino-esp8266

I would like to measure the temperature and humidity from DHT11 sensor and ESP8266.
To do so, I made some code by using two libraries.
But none of these can give me an accurate number of humidity and temperature value.
All I can get an output are like followings.
Temperature = 21.0000
Humidity = 48.0000
Please give me a hint to upgrade my code.
First code
#include <DHTesp.h>
DHTesp dht;
void setup(){
Serial.begin(9600);
pinMode(0, INPUT);
dht.setup(0, DHTesp::DHT11);
}
void loop(){
Serial.print("Temperature = ");
Serial.println(dht.getTemperature(), 4);
Serial.print("Humidity = ");
Serial.println(dht.getHumidity(), 4);
delay(1000);
}
Seconde code
#include <DHT.h>
DHT dht(0, DHT11);
void setup() {
Serial.begin(9600);
pinMode(0, INPUT);
dht.begin();
}
void loop() {
float humidity = dht.readHumidity();
float temp = dht.readTemperature();
delay(500);
Serial.println(humidity);
}

From DHT11 datasheet, it only supports resolution to 1 degree Celsius and 8bits for humidity leading to the integer like floats.
Also something to keep in mind is the units that the DHT11 and DHT22 output.
Temperature is returned as Celsius and humidity is a value between 0 - 100 representing the relative humidity.
To convert between Celsius and Fahrenheit, you can use this formula
Serial.print((int)round(1.8*temp+32));

Related

Issue with sending a string from raspberry pi to arduino using i2c

I want to send multibyte integers,(eg. 1000,10000, etc) from raspberry pi to arduino. It can either be in the form of int or string(will convert it into integer on arduino's side) through i2c. Now, I am able to send data but only till 255, If I try to send 1000, the output on ARduino serial terminal will be 232 and not 1000. I tried to search over the internet for like 4-5 hours, but no luck. Can someone please guide me?
import smbus
import time
bus = smbus.SMBus(1)
address = 0x04
a=1000
#a=str(a)
def writeString(a,b,c,d):
bus.write_i2c_block_data(address, a, [b, c, d])
return -1
while True:
try:
writeString(1000,a,5,0)
time.sleep(1) #delay one second
except KeyboardInterrupt:
quit()
Arduino:
#include <Wire.h>
int data [4];
int x = 0;
void setup() {
Serial.begin(9600);
Wire.begin(0x04);
Wire.onReceive(receiveData); //callback for i2c. Jump to void recieveData() function when pi sends data
}
void loop () {
delay(100); //Delay 0.1 seconds. Something for the arduino to do when it is not inside the reciveData() function. This also might be to prevent data collisions.
}
void receiveData(int byteCount) {
while(Wire.available()) { //Wire.available() returns the number of bytes available for retrieval with Wire.read(). Or it returns TRUE for values >0.
data[x]=Wire.read();
x++;
}
Serial.println("----");
Serial.print(data[0]);
Serial.print("\t");
Serial.print(data[1]);
Serial.print("\t");
Serial.print(data[2]);
Serial.print("\t");
Serial.println(data[3]);
// Serial.print("----");
}
I2C sends and receives BYTES. 1000 in hex is 0x3E8. 232 in hex is 0xE8. Only the low byte is sent.

2 DC motors & 1 servo for steering rc car

im working on an RC car project and im using 2 DC motors as a rear wheels ,one servo motor on front for steering with a nano arduino as a microcontroller, HC 06-slave bluetooth receiver, and L298N module for Fwd/Rev and PWM. for my transmitter im using nano arduino a joystick and HC-06 master.
i need my joystick Y axis to drive fwd/rev and X axis for steering. i manged to test the servo alone for X axis steering and it worked, also when tested the code for FWD/REV on Y axis it worked.. however when i combine my code it doesn't work my servo starts shaking and my DC motors start responding to x and y!!
can someone help me pls.
here are the codes im using:
Master code (transmitter);
// == MASTER DEVICE - Joystick ==
//int xAxis, yAxis;
void setup() {
Serial.begin(9600); // Default communication rate of the Bluetooth
module
}
void loop() {
xAxis = analogRead(A0); // Read Joysticks X-axis
yAxis = analogRead(A1); // Read Joysticks Y-axis
// Send the values via the serial port to the slave HC-05 Bluetooth
device
Serial.write(xAxis/4); // Dividing by 4 for converting from 0 -
1023 to 0 - 256, (1 byte) range
Serial.write(yAxis/4);
delay(20);
}
slave code (servo only);
#include <Servo.h>
Servo myServo;
int yAxis;
void setup() {
myServo.attach(3);
Serial.begin(9600); // Default communication rate of the Bluetooth
module
}
void loop() {
yAxis = 510 / 4;
// Read the incoming data from the Joystick, or the master
Bluetooth device
if(Serial.available() > 0){ // Checks whether data is comming from
the serial port
yAxis = Serial.read(); // Reads the data from the serial port
}
delay(10);
myServo.write(yAxis);
delay(10);
}
slave code for DC motors FWD/REV;
#include <Servo.h>
#define enA 9
#define in1 4
#define in2 5
#define enB 10
#define in3 6
#define in4 7
//int servoPin = 3;
int xAxis;
unsigned int x = 0;
unsigned int y = 0;
int motorSpeedA = 0;
int motorSpeedB = 0;
//Servo Servo1;
void setup() {
pinMode(enA, OUTPUT);
pinMode(enB, OUTPUT);
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
pinMode(in3, OUTPUT);
pinMode(in4, OUTPUT);
Serial.begin(9600); // Default communication rate of the Bluetooth module
// Servo1.attach(servoPin);
}
void loop() {
// Default value - no movement when the Joystick stays in the center
x = 510 / 4;
y = 510 / 4;
// Read the incoming data from the Joystick, or the master Bluetooth device
while (Serial.available() >= 2) {
x = Serial.read();
// delay(10);
// y = Serial.read();
}
delay(10);
// Convert back the 0 - 255 range to 0 - 1023, suitable for motor control code below
xAxis = x*4;
// yAxis = y*4;
// Y-axis used for forward and backward control
if (xAxis < 470) {
// Set Motor A backward
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
// Set Motor B backward
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
// Convert the declining Y-axis readings for going backward from 470 to 0 into 0 to 255 value for the PWM signal for increasing the motor speed
motorSpeedA = map(xAxis, 470, 0, 0, 255);
motorSpeedB = map(xAxis, 470, 0, 0, 255);
}
else if (xAxis > 550) {
// Set Motor A forward
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
// Set Motor B forward
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
// Convert the increasing Y-axis readings for going forward from 550 to 1023 into 0 to 255 value for the PWM signal for increasing the motor speed
motorSpeedA = map(xAxis, 550, 1023, 0, 255);
motorSpeedB = map(xAxis, 550, 1023, 0, 255);
}
// If joystick stays in middle the motors are not moving
else {
motorSpeedA = 0;
motorSpeedB = 0;
}
if (motorSpeedA < 70) {
motorSpeedA = 0;
}
if (motorSpeedB < 70) {
motorSpeedB = 0;
}
analogWrite(enA, motorSpeedA); // Send PWM signal to motor A
analogWrite(enB, motorSpeedB); // Send PWM signal to motor B
}
i want to combine them so one of the axis is for DC motors FWD/REV and the other axis is for servo motor right/left.
You must be more explicit with the data you send.
Don't send x=20,y=30 as char[2]={20,30}.
A minimum would be char[4]={'x',20,'y',30}.
Then you will check that you receive complete datagram of 4 char, and then you can check that you don't confuse x with y.

Serial monitor constantly say 0 when using arduino and sound sensor

I am having trouble with the arduino sound sensor and LEDs. I keep on getting the value of 0 in my serial monitor, the same thing happens with another sound sensor that I have. I am currently trying to make it light up the LEDs based on the sound but with the serial monitor reading 0 it will not activate the code. There should be a picture attached. The lights on the sound sensor is lighting up so I know the GND and 5V is working. Since it is hard to tell I am using 330 ohm resisters. I got the sound sensor from an elegoo starter kit, so I know it might be cheap. The picture is in the link at the end. Thank you.
int MicPin = A0;
int MicValue1 = 0;
int MicValue2 = 0;
int led1 = 2;
int led2 = 4;
int led3 = 6;
int led4 = 8;
void setup() {
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
pinMode(led4, OUTPUT);
pinMode(MicPin, OUTPUT);
Serial.begin(9600);
}
void loop() {
MicValue1 = analogRead(MicPin);
Serial.println(MicValue1);
delay(1);
MicValue2 = analogRead(MicPin);
Serial.println(MicValue2);
if (MicValue1 - MicValue2 > 1) {
digitalWrite(led1, HIGH);
delay(2000);
}
else {
digitalWrite(led1, LOW);
}
}
enter image description here
I assume that you have a simple analog-output sensor module that provides 10bit analog values based on the environment volume level. If this assumption is correct, you wired all pins correctly and the received value is always out of range or at the maximum, you maybe had to integrate a resistor to get a valid value. Try a small resistor and increase the resistance until you receive suitable values. Maybe the documentation of your module provides further information.
There is a small rotating knob connected to the sensor on which we need to rotate to adjust particular resistance values, you can see different values in serial monitor out.
Useful link

Servo continuous rotation Arduino Serial

I'm working on a Bluetooth controlled Arduino robotic arm.
I want that when I send an integer, a servo moves, and when I send another Int, it stops. All I have found on forums are systems where the servo moves to a specific position, but I want it to really rotate, by incrementing its angle.
Here is my code, which doesn't work:
#include <Servo.h>
int val;
int angle;
int charsRead;
char buffer[10];
Servo servo;
void setup() {
Serial.begin(9600);
servo.attach(6);
angle = servo.read();
}
void loop() {
servo.write(170);
serialCheck();
if(val == 4021){
servo.write(angle++);
delay(50);
}
}
else if(val == 4022){
servo.write(angle);
}
serialCheck();
}
void serialCheck(){
while(Serial.available() > 0){
charsRead = Serial.readBytesUntil('\n', buffer, sizeof(buffer) - 1);
buffer[charsRead] = '\0';
val = atoi(buffer);
Serial.println(val);
}
}
The app I use basically sends '4021' when I long press a button, and sends '4022' when I release it.
I've been working on this for hours and I haven't found anyone on any forum who has had the same issue...
Please help.
Your problem lies here:
void loop() {
servo.write(170);
...
}
What this piece of code does is set servo angle to 170 at every iteration of loop. As this will happen thousands times per second, it will essentially overwrite any servo settings introduced via serial commands. What you should do is to move servo.write(170); to setup(), before servo.read(), which I think will yield middle position currently, or even some undefined result. According to Arduino documentation it will:
Read the current angle of the servo (the value passed to the last call
to write()).
And BTW: servo has limited range of movement, so you should check if the desired angle doesn't exceed servo limits.

How to convert arduino's digital output in terms of frequency

I am using a analog-output sound sensor module where the output of the sensor module is connected to the arduino and can see arduino is doing Ato D conversion and displaying integers from range 0 to 1023.
But I need to calculate the frequency of the sound getting measure from the sensor.
so could you help me, hwo to calculate the frequecy from this Ato D converted values from arduino.
You don't really need to to ADC conversions do you? All you need to do is detect a rising edge on the input and then count those. Since your sensor will output low-high-low sequences, and since the Arduino will register HIGH as over a certain voltage, that should be adequate.
This code will measure up to around 200 kHz, from an input connected to digital pin 8 on the board:
// Input: Pin D8
volatile boolean first;
volatile boolean triggered;
volatile unsigned long overflowCount;
volatile unsigned long startTime;
volatile unsigned long finishTime;
// timer overflows (every 65536 counts)
ISR (TIMER1_OVF_vect)
{
overflowCount++;
} // end of TIMER1_OVF_vect
ISR (TIMER1_CAPT_vect)
{
// grab counter value before it changes any more
unsigned int timer1CounterValue;
timer1CounterValue = ICR1; // see datasheet, page 117 (accessing 16-bit registers)
unsigned long overflowCopy = overflowCount;
// if just missed an overflow
if ((TIFR1 & bit (TOV1)) && timer1CounterValue < 0x7FFF)
overflowCopy++;
// wait until we noticed last one
if (triggered)
return;
if (first)
{
startTime = (overflowCopy << 16) + timer1CounterValue;
first = false;
return;
}
finishTime = (overflowCopy << 16) + timer1CounterValue;
triggered = true;
TIMSK1 = 0; // no more interrupts for now
} // end of TIMER1_CAPT_vect
void prepareForInterrupts ()
{
noInterrupts (); // protected code
first = true;
triggered = false; // re-arm for next time
// reset Timer 1
TCCR1A = 0;
TCCR1B = 0;
TIFR1 = bit (ICF1) | bit (TOV1); // clear flags so we don't get a bogus interrupt
TCNT1 = 0; // Counter to zero
overflowCount = 0; // Therefore no overflows yet
// Timer 1 - counts clock pulses
TIMSK1 = bit (TOIE1) | bit (ICIE1); // interrupt on Timer 1 overflow and input capture
// start Timer 1, no prescaler
TCCR1B = bit (CS10) | bit (ICES1); // plus Input Capture Edge Select (rising on D8)
interrupts ();
} // end of prepareForInterrupts
void setup ()
{
Serial.begin(115200);
Serial.println("Frequency Counter");
// set up for interrupts
prepareForInterrupts ();
} // end of setup
void loop ()
{
// wait till we have a reading
if (!triggered)
return;
// period is elapsed time
unsigned long elapsedTime = finishTime - startTime;
// frequency is inverse of period, adjusted for clock period
float freq = F_CPU / float (elapsedTime); // each tick is 62.5 ns at 16 MHz
Serial.print ("Took: ");
Serial.print (elapsedTime);
Serial.print (" counts. ");
Serial.print ("Frequency: ");
Serial.print (freq);
Serial.println (" Hz. ");
// so we can read it
delay (500);
prepareForInterrupts ();
} // end of loop
More discussion and information at Timers and counters.
As I suggested you in the other thread, the best is to
filter
amplify
apply a threshold
measure the time between edges
Steps 1, 2, 3 can be performed in software but it is MUCH better to perform them in hardware. The fourth step is what Nick Gammon solution is about... But you have to first make steps 1,2,3 in HW otherwise you will receive a lot of "noisy" readings

Resources