I got this weather station and I am trying to get the data of the station to a website with this ESP32 as an school project. But the weather station isn't original as it is on the hyperlink, it got modified by an former student. So the cable coming from the anemometer and the wind direction indicator got cut of, so the four cable inside (GND, 3.3V, wind speed data, wind direction data) could fit in the ESP32. First I try to get the anemometer running. I got the Signal from the anemometer to the serial monitor with this code, which works fine:
int windSpeed = A0;
int outputValue = 0;
void setup() {
Serial.begin(9600);
}
void loop() {
outputValue = analogRead(windSpeed);
Serial.println(outputValue);
if(outputValue > 0) {
Serial.println("high");
}
}
So the next thing I wanted to do was to was calculating the wind speed. I found this code in the internet and adjusted it so it would fit to my ESP32.
const int RecordTime = 3; //Define Measuring Time (Seconds)
const int SensorPin = A0; //Define Interrupt Pin (2 or 3 # Arduino Uno)
int InterruptCounter;
float WindSpeed;
void setup()
{
Serial.begin(9600);
}
void loop() {
meassure();
Serial.print("Wind Speed: ");
Serial.print(WindSpeed); //Speed in km/h
Serial.print(" km/h - ");
Serial.print(WindSpeed / 3.6); //Speed in m/s
Serial.println(" m/s");
}
void meassure() {
InterruptCounter = 0;
attachInterrupt(digitalPinToInterrupt(SensorPin), countup, RISING);
delay(1000 * RecordTime);
detachInterrupt(digitalPinToInterrupt(SensorPin));
WindSpeed = (float)InterruptCounter / (float)RecordTime * 2.4;
}
void countup() {
InterruptCounter++;
}
I can upload this code to the ESP32 and it prints the massages in the serial monitor, but it doesn`t get the interrupt.
What´s wrong?
Edit: Thank you, now I get the wind speed in the seriell monitor, but unfortunately it doesn't sends many signals. But RISING in attachInterrupt(digitalPinToInterrupt(SensorPin), countup, RISING); should´ve solve this should´nt it?
Edit no. 2:
#PMF This is written in the manual (The manual is german but I will continue to write in english so it may help other people):
Das Windrad ist mit einem Magnetschalter gekoppelt, der bei einer Umdrehung zwei Impulse abgibt. Das Datenblatt besagt, dass die Impulsfrequenz in Hz mit dem Faktor 0,33 multipliziert werden muss, um die Windgeschwindigkeit in m/s zu erhalten. Die Rotationsfrequenz ergibt sich aus der Zeitdifferenz zwischen zwei Impulsen in Sekunden, multipliziert mit dem Faktor 2 (der Sensor liefert bei einer Umdrehung zwei Impulse). Die Rotationsfrequenz ist dann der Kehrwert der Zeitdifferenz. Wenn dieser Wert mit dem Faktor 0,66 multipliziert wird, ist das Ergebnis die Windgeschwindigkeit in m/s. Die Windgeschwindigkeit in km/h lässt sich berechnen, indem die Windgeschwindigkeit in m/s mit dem Faktor 3,6 multipliziert wird. Mit anderen Worten: Eine Umdrehung des Windrads pro Sekunde ist gleichbedeutend mit der Windgeschwindigkeit 2,4 km/h. (1 rotation = 2.4 kph)
So if I am right the code should also be right, but the interrupt counter seems to just go up while there is an interrupt, even if I put the anemometer on the table in a certain position it just counts up as you can see in the following screenshot of the seriell monitor while the anemometer is just laying on the table:
"A0" is defined as 0 on the ESP32 (for most variants at least). I would not use it at all, because the ESP can use analog in on most pins and uses no pin mapping. Just use the GPIO pin number directly. The interrupt handling anyway works on digital inputs, not on analog inputs, so any reference to an analog pin would at least be confusing.
So change to SensorPin = 36; and make sure you do pinMode(SensorPin, INPUT); in setup().
Related
I am using Arduino Nano with HX711 scales module and cc2541 Bluetooth module(Bluetooth 4.0) to send data to Android device.
#define RX 11
#define TX 10
#include "HX711.h"
HX711 scale(A1, A0);
float scale_calibration = -13.5;
float mass,massround;
float units;
int out;
#include <SoftwareSerial.h>
SoftwareSerial bluetooth(TX, RX);
void setup()
{
bluetooth.begin(9600);
scale.set_scale();
scale.tare();
scale.set_scale(scale_calibration);
}
void loop()
{
for(int i = 0;i < 10; i ++) units =+ scale.get_units(), 1;
units / 10;
mass = units * 0.035274;
massround=mass;
out = round(massround);
out = abs(out);
if(out<0)
{
out=0;
scale.tare();
}
bluetooth.println(out);
}
If I run Arduino using USB coonected to my PC, the scales work perfect and give right results via Bluetooth. However, when I run Arduino using battery (not connected to PC), I get 0-3 grams value, while there is nothing on the scales. So because of that all measurements are incorrect. How can I fix this problem?
When your Arduino is powered from USB, it and the HX711 probably have both VCC and VDD at +5 volts, making the 'reference' voltage (VDD) 5 volts.
When running off battery, the hardware is receiving ~3 volts, and if VCC and VDD are shorted together on the HX711, it might 'kinda work' but would give spurious results.
There's probably jumpers or bridges to set VCC and VDD on both the arduino and the load cell. CAUTION! I'm just guessing here, and be sure to read the tech docs before changing the voltage settings, it's easy to cook these little circuits with a minor change in voltages.
This might be better asked in a hardware or electrical engineering channel.
I'm new to Arduino and I'm working on project for school. I'm trying to create a device that can detect fire and give direct feedback to the user in form of light, movement, and sound.
I'm running into a couple of issues with my code. What I would like to accomplish is that my device give direct feedback when it detects fire in form of light (LED's) and movement (servo) but not in sound.
Everything is working fine except the piezo buzzer and the led lights. The servo motor starts turning 180 degrees when the flame sensor detects fire but the leds arent shining. I don't quite understand why my leds arent shining.. is there something wrong with my code. Alse the problem with the buzzer is that the buzzer has to go off when the flame sensor detects fire but only after 15 minutes. Now it just goes off in an instant. Also the delay function for the servo seems to have influence on the duration of the piezo buzzer. I would like to keep that separate from each other. I'm working with the delay function now but it doesn't seem to work. I know I have to use the millis() function but I don't know how to change my delay function to millis.
The code:
#include <Servo.h>
Servo myservo;
const int servoPin = D8; // Servo pin op D8
const int flamePin = D6; // Flame sensor pin op D6
const int buzzerPin = D5; // Piezo buzzer op D5
const int ledPin1 = D3; // Led licht 1 op D3
const int ledPin2 = D7; // Led licht 2 op D7
int Flame = HIGH; // De waarde HIGH wordt gekoppeld aan wanneer de vlam aan staat
void setup() {
pinMode(flamePin, INPUT); // Flame sensor is input
myservo.attach(servoPin); // Servo is ouput
pinMode(buzzerPin, OUTPUT); //Piezo buzzer is output
pinMode(ledPin1, OUTPUT); //Led 1 is output
pinMode(ledPin2, OUTPUT); //led 2 is output
} //setup
void loop() {
Flame = digitalRead(flamePin); // Flame waarde wordt gekoppeld aan de waarde die de flamePin leest
if (digitalRead(flamePin) == HIGH) { // Wanneer de flame sensor vuur waarneemt
myservo.write(180); // Draait de servo 180 graden
delay(50); // Doet er 50ms over om naar de positie te komen
noTone(D5);
delay(50000);
tone(D5, 261, 50000);
digitalWrite(ledPin1, HIGH); //Led 1 gaat branden zodra vuur wordt waargenomen
digitalWrite(ledPin2, HIGH); //Led 2 gaat branden zodra vuur wordt waargenomen
}
else if (Flame == LOW){ // Wanneer de flame sensor geen vuur waarneemt
myservo.write(0); // Draait de servo niet
noTone(D5);
digitalWrite(ledPin1, LOW); //Led 1 staat uit
digitalWrite(ledPin2, LOW); //Led 2 staat uit
}
}//loop
millis will return the time passed since your board rebooted. So how do you know 15 minutes have passed? You remember the time you started waiting and from time to time you check if the moment of that time plus 15 minutes has passed.
So in order to trigger a buzzer 15 minutes after fire was detected:
fire detected -> store current timestamp (millis()) in a variable. Let's name it startTime.
in a loop frequently check if the current time (millis()) is >= startTime + 900000.
if so, start the buzzer, else continue checking your fire sensor input to go LOW.
I'm sure you know how to pour that into code!
I'm having a strange problem that I hope someone can help with. My sketch works perfectly when uploaded to my UNO, but when I unplug it and plug it back in, it doesn't work correctly. If I re-upload it, it works again until power is cycled.
Once uploaded, the LCD reads:
Ferm:73.4 73/75
Room:75.1 75/75
After cycling power:
Ferm:73.45 73/18
Room:74.83 75/18
So after cycling power, I now get 2 decimal places and the "high" temp is stuck at "18".
/*
The circuit:
* 5V to Arduino 5V pin
* GND to Arduino GND pin
* CLK to Analog #5
* DAT to Analog #4
*/
// include the library code:
#include "Wire.h"
#include "Adafruit_LiquidCrystal.h"
#include <OneWire.h>
#include <DallasTemperature.h>
//variables for temp readings
float fermTemp;
float fermTempL=100;
float fermTempH=5;
float roomTemp;
float roomTempL=100;
float roomTempH=5;
// set OneWire bus to digital PIN 4 on the Arduino
#define ONE_WIRE_BUS 4
// Setup OneWire instance
OneWire oneWire(ONE_WIRE_BUS);
// Pass oneWire reference to Dallas Temp
DallasTemperature sensors(&oneWire);
// Connect via i2c, default address #0 (A0-A2 not jumpered)
Adafruit_LiquidCrystal lcd(0);
void setup()
{
// set up the LCD's number of rows and columns:
lcd.begin(16, 2);
// turn on backlight
lcd.setBacklight(HIGH);
}
void loop() {
readtemp();
LCDPrint();
}
void readtemp()
{
// get data from sensors
sensors.requestTemperatures();
fermTemp = (sensors.getTempFByIndex(0));
roomTemp = (sensors.getTempFByIndex(1));
// check/set High and Low temp
if (fermTemp<fermTempL) {
fermTempL=fermTemp;
}
if (fermTemp>fermTempH) {
fermTempH=fermTemp;
}
if (roomTemp<roomTempL) {
roomTempL=roomTemp;
}
if (roomTemp>roomTempH) {
roomTempH=roomTemp;
}
}
void LCDPrint()
{
lcd.setCursor(0,0);
lcd.print("Ferm:");
lcd.print(fermTemp,1);
lcd.setCursor(11,0);
lcd.print(fermTempL,0);
lcd.print("/");
lcd.print(fermTempH,0);
lcd.setCursor(0,1);
lcd.print("Room:");
lcd.print(roomTemp,1);
lcd.setCursor(11,1);
lcd.print(roomTempL,0);
lcd.print("/");
lcd.print(roomTempH,0);
}
I counted your characters, 16 per line. If you have a 16X2 display, there might be characters printed beyond the screen. I suspect it was not really 18, but something larger, say 180 or 1800. That could have been a result of failed first attempt to read temperature. This reading is stuck with you as temp High. In your code, you should define a reasonable high temperature, such as 125. Don't update temp High if it is above the reasonable temperature.
To confirm it, print temp High to serial port and inspect the value.
i want made speed detection "device" using with Arduino and two ultrasonic hc-sr04 like this link. but I want to make it with ultrasonic instead by LDR.
from that link. how lasers and ldr work, like this
The resistors are used as pull-down resistors and I wired the sensors and put them in a case, to avoid them detecting surrounding light. For each case, a hole was drilled so that the laser beam can light the sensor while the ambient light does not affect the sensor.
The working principle is easy: an object that passes by will "cut" the laser beams, this means the LDR sensor will detect this sudden drop of light intensity. First I defined a threshold value under which the sensor is considered triggered, once the value is under threshold for the first sensor then Arduino waits for the second one to be triggered. During this waiting time it counts the elapsed time between the two events. When the second beam is interrupted, the timer stops and now is just simple math. The distance between the 2 sensors is known, the time between the two events is known, and speed can be computed as speed = distance/time.
Below the Arduino code:
/*
by Claudiu Cristian
*/
unsigned long time1;
int photocellPin_1 = 0; // 1st sensor is connected to a0
int photocellReading_1; // the analog reading from the analog port
int photocellPin_2 = 1; // 2nd sensor is connected to a1
int photocellReading_2; // the analog reading from the analog port
int threshold = 700; //value below sensors are trigerd
float Speed; // declaration of Speed variable
float timing;
unsigned long int calcTimeout = 0; // initialisation of timeout variable
void setup(void) {
// We'll send debugging information via the Serial monitor
Serial.begin(9600);
}
void loop(void) {
photocellReading_1 = analogRead(photocellPin_1); //read out values for sensor 1
photocellReading_2 = analogRead(photocellPin_2); //read out values for sensor 2
// if reading of first sensor is smaller than threshold starts time count and moves to calculation function
if (photocellReading_1 < threshold) {
time1 = millis();
startCalculation();
}
}
// calculation function
void startCalculation() {
calcTimeout = millis(); // asign time to timeout variable
//we wait for trigger of sensor 2 to start calculation - otherwise timeout
while (!(photocellReading_2 < threshold)) {
photocellReading_2 = analogRead(photocellPin_2);
if (millis() - calcTimeout > 5000) return;
}
timing = ((float) millis() - (float) time1) / 1000.0; //computes time in seconds
Speed = 0.115 / timing; //speed in m/s given a separation distance of 11.5 cm
delay(100);
Serial.print(Speed);
Serial.print("\n");
}
how to implement the code with ultrasonic HC-SR04 sensors?
the coding is problem for me. hopefully someone can help me...... :(
Please excuse my poor English !
There are already lots of examples on the internet, so if all you want to do is copy, google arduino sr04
But if you want to know how to do it...
The sr04 has 4 pins, vin, gnd, trigger, and echo.
Connect vin and ground to +5 and gnd
Connect trigger to a digital output pin
Connect echo to a digital input pin
Trigger by going low for 2 microseconds (us) and then high for 10 us then low again
Then get the results with a pulseIn from the echo pin
Read the data sheet for more information
I am trying to receive information from my sensor, however my output is just 0 all the time, is there something wrong in my code? Everything hardware related is done well.
loop()
{
long duration, inches, cm;
pinMode(pingPin, OUTPUT);
digitalWrite(pingPin, LOW);
delayMicroseconds(2);
digitalWrite(pingPin, HIGH);
delayMicroseconds(5);
digitalWrite(pingPin, LOW);
pinMode(pingPin, INPUT);
duration = pulseIn(pingPin, HIGH);
inches = microsecondsToInches(duration);
cm = microsecondsToCentimeters(duration);
Serial.print(inches);
Serial.print("in; ");
Serial.print(cm);
Serial.print("cm");
Serial.println();
}
long microsecondsToInches(long microseconds)
{
return microseconds / 74 / 2;
}
long microsecondsToCentimeters(long microseconds)
{
return microseconds / 29 / 2;
}
The sensor you have does not use PWM as a way of sending distance. Rather it uses a serail connection. The issue is that you do NOT have a extra serial hardware on the Arduino.
You could use the arduino's serail port to read the sensors data, but you would not be able to log anything to the screen
The speed at which the serial connection runs is 9600 baud, which is to fast to emulate in software.
I advice you to buy a sensor that uses the standard PWM mode of communication. Doing this will save a several headaches .But I should tell you there is a way. It is using the software serial library. The library will help you use digital pins like they are serail pins.
http://arduino.cc/en/Reference/SoftwareSerial
http://www.suntekstore.com/goods-14002212-3-pin_ultrasonic_sensor_distance_measuring_module.html
http://iw.suntekstore.com/attach.php?id=14002212&img=14002212.doc
You are using code for the Parallax PING, which uses a different protocol from the one you have. Here is a link to the datasheet of your sensor. It outputs through standard serial at 9600bps every 50ms.
After many tries and thanks to the help of John b, this was figured out as the proper answer on how to use this kind of sensor properly, it works exactly as needed, the output being perfectly measured
#include <SoftwareSerial.h>
// TX_PIN is not used by the sensor, since that the it only transmits!
#define PING_RX_PIN 6
#define PING_TX_PIN 7
SoftwareSerial mySerial(PING_RX_PIN, PING_TX_PIN);
long inches = 0, mili = 0;
byte mybuffer[4] = {0};
byte bitpos = 0;
void setup() {
Serial.begin(9600);
mySerial.begin(9600);
}
void loop() {
bitpos = 0;
while (mySerial.available()) {
// the first byte is ALWAYS 0xFF and I'm not using the checksum (last byte)
// if your print the mySerial.read() data as HEX until it is not available, you will get several measures for the distance (FF-XX-XX-XX-FF-YY-YY-YY-FF-...). I think that is some kind of internal buffer, so I'm only considering the first 4 bytes in the sequence (which I hope that are the most recent! :D )
if (bitpos < 4) {
mybuffer[bitpos++] = mySerial.read();
} else break;
}
mySerial.flush(); // discard older values in the next read
mili = mybuffer[1]<<8 | mybuffer[2]; // 0x-- : 0xb3b2 : 0xb1b0 : 0x--
inches = 0.0393700787 * mili;
Serial.print("PING: ");
Serial.print(inches);
Serial.print("in, ");
Serial.print(mili);
Serial.print("mili");
Serial.println();
delay(100);
}