With the following code I get a log like the one below. Why is that?
int analogPin = 5;
int val = 0;
void setup(void) {
Serial.begin(9600);
}
void loop(void) {
val = analogRead(analogPin);
Serial.print("Analog reading = ");
Serial.println(val);
}
Result:
Analog reading = 998
Analog reading = 981
Analog reading = 511
Analog reading = 159
Analog reading = 24
Analog reading = 108
Analog reading = 439
Analog reading = 946
Analog reading = 1023
Analog reading = 420
Analog reading = 116
Analog reading = 25
Analog reading = 151
Analog reading = 542
Analog reading = 997
Analog reading = 982
Analog reading = 513
Analog reading = 161
Analog reading = 25
Analog reading = 107
Analog reading = 437
Analog reading = 945
Analog reading = 1023
Analog reading = 421
Analog reading = 117
Analog reading = 25
Analog reading = 150
Analog reading = 541
Analog reading = 997
Analog reading = 983
Analog reading = 515
Analog reading = 162
Analog reading = 25
Analog reading = 107
Analog reading = 437
Analog reading = 945
Analog reading = 1023
Analog reading = 422
Analog reading = 117
Analog reading = 25
Analog reading = 149
Analog reading = 540
Analog reading = 997
Analog reading = 983
Analog reading = 516
Analog reading = 162
Analog reading = 25
Analog reading = 107
Analog reading = 436
Analog reading = 945
Analog reading = 1023
Analog reading = 422
Analog reading = 117
Analog reading = 25
Analog reading = 150
Analog reading = 540
Analog reading = 998
Analog reading = 982
Analog reading = 516
Analog reading = 162
Analog reading = 25
Analog reading = 108
Analog reading = 437
Is the result just noise?
And as soon as I plug in a cable I see the following pattern:
Analog reading = 0
Analog reading = 0
Analog reading = 0
Analog reading = 0
Analog reading = 0
Analog reading = 0
Analog reading = 0
Analog reading = 0
Analog reading = 0
Analog reading = 72
Analog reading = 447
Analog reading = 1023
Analog reading = 1023
Analog reading = 0
Analog reading = 0
Analog reading = 0
Analog reading = 0
Analog reading = 0
Analog reading = 0
Analog reading = 0
Analog reading = 0
Analog reading = 0
Analog reading = 118
Analog reading = 849
Analog reading = 1023
Analog reading = 835
Analog reading = 0
Analog reading = 0
Analog reading = 0
Analog reading = 0
Analog reading = 0
Analog reading = 0
Analog reading = 0
Analog reading = 0
Analog reading = 40
Analog reading = 401
Analog reading = 1023
Analog reading = 1023
Analog reading = 0
Analog reading = 0
Analog reading = 0
Analog reading = 0
Analog reading = 0
Analog reading = 0
Analog reading = 0
Analog reading = 0
Analog reading = 0
Analog reading = 89
Analog reading = 475
Analog reading = 1023
Analog reading = 1023
Is that my heartbeat or so??? No idea what can have such an influence on a empty pin.
Yes, it's quite normal for an unconnected analog pin to produce random noise. From the documentation (emphasis mine):
If it is important for a sequence of values generated by random() to differ, on subsequent executions of a sketch, use randomSeed() to initialize the random number generator with a fairly random input, such as analogRead() on an unconnected pin.
With regards to the values that you see when you plug in the cable, whether or not they make sense depends on the signal that you feed into the pin. If there's some discrepancy, it might be worth looking at the signal with an oscilloscope.
Also, see How come analogRead reads oscillating values from 0 to 1023 when no actual input is present?
Its a floating input. if a pin its not connected to anything or directly connected to a 5V source.
The arduino Button tutorial explains this a bit.
For more details look at the wikipedia Pull-up Resistor page
I have PPG sensor board and Arduino Mega. I tried your code on my kit. When PPG sensor board detect my heart rate it begin to change all zeros. Let me explain the serial monitor output. Firstly everywhere is 0. My heart rate is detected. It is not 0 now. It is full of numbers instead. These are not noise only. These are noise+real heart rate numbers for me now. Arduino shows graphical peaks at its detection frequency, I guess.
Related
I am running an Arduino Nano (with a RasPi to send to Thingspeak). It measures different things in my office, temp, hum, CO2 AND it waters my plant. :-)
I have a small problem with my code for the plant watering.
Here is what I want it to do:
Loop
Measure Soil moisture
If > 60 run pump for 2 seconds
Delay 180 seconds (this delay goes for all sensors)
I have a problem! This is what the code actually does:
Loop
Measure Soil moisture
If > 60 run pump for 2 seconds
This means that it just keeps watering away, much faster than the water can absorb the water.
Please help me get the delay working.
Thank you. :-)
This is the code I am running:
void loop()
{
int temp = 0, hum = 0, moist = 0, level = 0, co2_ppm = 0;
moist = read_soil_moisture(soil_pin);
temp = read_temp();
hum = read_humidity();
level = read_water_level(water_pin);//reads water level
co2_ppm = CO2_PPM();
//print_sensor(hum, temp, moist, level,co2_ppm);
temp = read_temp();
if (temp >= 3)
{
temp -= 3;
}
else
{
temp = 0;
}
log_sensor(hum, temp, moist, level, co2_ppm); //prints values of sensors to UART
if (moist > 60)
{
digitalWrite(pump, LOW);//Setting relay pin high
delay(2000);//keeps relay pin high for 2 seconds
digitalWrite(pump, HIGH);//Setting relay pin low
}
else
{
digitalWrite(pump, HIGH);//keep relay pin low
}
delay(180000);//take a reading every 180 seconds
Github repo: https://github.com/pkold/Self-watering-plant-system
Do you have readings from the moisture sensor when it is complete dry and when it is fully emerged in water?
When i look at your github repo the moisture value is a percentage which increase when the moisture rises.
Turning on the pump when the moisture is already above 60 will only increase the sensor value.
I want to implement oil painting filter in OpenCL,but the output image is always black and I cannot figure out why.
Here's the kernel code:
__kernel void oil_painting(__global const char* R,__global const char* G,__global const char* B,
__global char* r,__global char* g,__global char* b)
{
int i=get_global_id(0);
int j=get_global_id(1);
int i1,j1,k;
int avgR[256],avgG[256],avgB[256],intensity_count[256];
int max_pixels=0,max_intensity=0,current_intensity;
for (i1=0;i1<4;i1++) {
for (j1=0;j1<4;j1++) {
current_intensity=(((R[(i+i1)*512+j+j1]+
G[(i+i1)*512+j+j1]+
B[(i+i1)*512+j+j1])/3)*70)/255;
intensity_count[current_intensity]++;
if (intensity_count[current_intensity]>max_pixels) {
max_pixels=intensity_count[current_intensity];
max_intensity=current_intensity;
}
avgR[current_intensity]+=R[(i+i1)*512+j+j1];
avgG[current_intensity]+=G[(i+i1)*512+j+j1];
avgB[current_intensity]+=B[(i+i1)*512+j+j1];
}
}
r[i*512+j]=min(255,max(0,avgR[max_intensity]/max_pixels));
g[i*512+j]=min(255,max(0,avgG[max_intensity]/max_pixels));
b[i*512+j]=min(255,max(0,avgB[max_intensity]/max_pixels));
}
Code snippets like the following are going to get you into a lot of trouble:
current_intensity=(((R[(i+i1)*512+j+j1]+
G[(i+i1)*512+j+j1]+
B[(i+i1)*512+j+j1])/3)*70)/255;
Consider what happens for a pixel of <127,127,127>:
127 + 127 + 127 = 125 (truncated because `char` is only 8 bytes...)
125 / 3 = 41
41 * 70 = 54 (truncated because `char` is only 8 bytes...)
54 / 255 = 0 (this will always equal 0!)
So intensity_count will only ever have its 0-th index incremented, and nothing else.
Casting everything to int might fix this problem.
current_intensity=((((int)R[(i+i1)*512+j+j1]+
(int)G[(i+i1)*512+j+j1]+
(int)B[(i+i1)*512+j+j1])/3)*70)/255;
New output:
127 + 127 + 127 = 381
381 / 3 = 127
127 * 70 = 8890
8890 / 255 = 34
But you've now got a new problem: what if the values are any higher than 127? Suppose we change this to use <200, 200, 200> instead?
-56 + -56 + -56 = -168 (`char` only has a range in [-128, 127]! You're overflowing!)
-168 / 3 = -56
-56 * 70 = -3920
-3920 / 255 = -15
And now you've crashed your program because either you're going to attempt to access index -15, which is illegal, or you're going to attempt to access index 2^64 - 15 - 1, which is going to still be illegal. Either way, you're going to get bad results.
The simplest solution is to change your kernel arguments to global uchar * instead of global char *, and then make sure that any and all arithmetic is casted upwards to int or long to ensure that overflow doesn't take place.
I wrote a sketch on my Arduino Mega when I was prototyping. Afterwards, I flashed it as is to a atmega328 chip. I got odd results all over the sketch. To fix it, I copied module by module over to a new IDE windows and that is when I noticed something fishy with the analogWrite functions. In order to take away all other variables, I uploaded this sketch which is a slightly modified FADE example sketch
int led = 6;
int brightness = 0;
int fadeAmount = 5;
void setup() {
Serial.begin(9600);
pinMode(led, OUTPUT);
}
void loop() {
Serial.println(brightness);
analogWrite(led, brightness);
brightness = brightness + fadeAmount;
if (brightness == 0 || brightness == 255) {
fadeAmount = -fadeAmount ;
}
delay(1000);
}
It uploads perfectly fine with no errors and I attached an led and resistor to that pin. when the chip starts running the code, all I get the led flashing and the serial data like this
.5
.0
.5
.0
.5
.0
.5
.0
.5
.0
.5
.0
.5
.10
What can be wrong with it???
Strange things are happening. I ran the program after copying and pasting your code and got the expected result:
0
5
10
15
20
25
30
35
40
45
50
55
60
65
70
75
80
85
90
95
100
105
110
115
120
125
130
135
140
145
150
155
160
165
170
175
180
185
190
195
200
205
210
215
220
225
230
235
240
245
250
255
250
245
240
235
230
225
220
Are you sure you have pasted the exact code that produces the unexpected results in your side? The dots in front of the numbers are just one of many strange things. Of course the alternating values are another. As is the .10 that suddenly appears after the seros and fives. In short, the fishiness seems to be unrelated to analogwrite.
Unless it is a hardware problem. What value resistor? Are the resistor and LED in series? Does the LED flash with a frequency of 0.5 Hz and a duty cycle of 0.5? or not?
BTW, RBerteig would be correct if your condition checked with 256 instead of 255. His version is indeed better, but if this were the problem you would see a different behaviour
An obvious problem is with this line:
if (brightness == 0 || brightness == 255) {
Since you are modifying brightness by adding (or subtracting) 5 on each iteration and 256 is not divisible by 5, neither endpoint is going to test well.
Change the == test to an inequality.
if (brightness <= 0 || brightness >= 255) {
I have 6 sensors connected to the pin A0, A1, A2, A3, A4, A5 and I am trying to get readings from each sensor. I have a analogread() function inside of a for loop and it does not work.
If I just trigger the sensor at A0, all other sensors will have the same reading as that one even if they are not triggered. I used a voltage meter to test the voltage of each pin and only got voltage at A0 when the A0 sensor is triggered. So I believe this is a coding problem.
Here is my code:
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
}
// the loop routine runs over and over again forever:
void loop() {
// read the input on analog pin 0~5:
for(int i = 0; i < 6; i++){
int sensorValue0 = analogRead(i);
delay(700);
// Convert the analog reading (which goes from 0 - 1023) to voltage range (0 - 5V);
float voltage0 = sensorValue0 * (5.0 / 1023.0);
// print out the value you read:
Serial.print(voltage0);Serial.print(" i = ");
Serial.print(i);Serial.print(" ; ");
if (i == 5) Serial.println(" ");
}
}
I just set up some voltage dividers, consisting of combination of various R1 and R2=1k and hooked them up to the analog inputs of an Arduino. Using your code, I received the following data (S0 = raw reading, V0 = calculated voltage)
R1 S0 V0
220 841 4.11
470 695 3.40
1k 511 2.50
2k2 318 1.55
4k7 179 0.87
6k8 128 0.63
This looks fine. Your code is correct. There's definitely something wrong with your wiring.
I am new to Arduino and to this forum and this is my first Arduino project besides the tutorials.
I am trying to control a servo using a rc transmitter/receiver and the Arudino. The reason why I am using a Arduino instead of connecting the servo directly to the RC receiver is that the RC can only generate a PWM of 1000µs to 2000µs while I need a PWM of 600µs to 2400µs to get the full range of motion of my servo. What I have tried to do is to read the value from pulseIn(), then mapping this value to 0 to 180 degree as written in code below (which utilizes servo library).
However, with this code, the motor behaviour is weird. As I move the radio transmitter control stick through its range of motion, the motor rotates from 0 to 45 degrees, back from 45 to 0, 0 to 45, and back to 0 again instead of sweeping from 0 to 180 degrees. Could anyone please offer some help or advice?
Thank you very much
#include <Servo.h>
Servo myservo;
int ch1;
int ch2;
int ch3;
int degree;
void setup() {
pinMode(7, INPUT);
myservo.attach(9);
Serial.begin(9600);
}
void loop() {
ch3 = pulseIn(7, HIGH, 25000);
degree = ((ch3-1250)* 180)/700;
Serial.print("Channel 3:");
Serial.println(ch3);
myservo.write(degree);
delay(5); // waits 5ms for the servo to reach the position
}
You are overflowing the int data type. The signed value can only be -32768 to +32767. See int docs
Your formula is all int's and the compiler will not guess that you might need a larger intermediate value. The multiply by 180 is a red flag. (2000-1250)*180 = 135000 = boom
To understand the math, break down a formula into the individual operations as shown in the test program below. That is essentially what the compiler is doing for you.
Run the program below and you will see the failure. Just after the out value reaches 45, the intermediate value overflows and the formula breaks down.
in: 1040 out: 39 t0: -210 t1: 27736 t2: 39
in: 1048 out: 41 t0: -202 t1: 29176 t2: 41
in: 1056 out: 43 t0: -194 t1: 30616 t2: 43
in: 1064 out: 45 t0: -186 t1: 32056 t2: 45
in: 1072 out: -45 t0: -178 t1: -32040 t2: -45
in: 1080 out: -43 t0: -170 t1: -30600 t2: -43
Use this program below as a test fixture. Modify the data types to use unsigned int and you will be able to make the output behave as you need.
int ch3;
int degree;
void setup() {
ch3 = 1000;
Serial.begin(9600);
}
void loop() {
int t0, t1, t2;
degree = ((ch3-1250)* 180)/700;
t0 = ch3 - 1250;
t1 = t0 * 180;
t2 = t1 / 700;
Serial.print("in: ");
Serial.print(ch3);
Serial.print(" out: ");
Serial.print(degree);
Serial.print(" t0: ");
Serial.print(t0);
Serial.print(" t1: ");
Serial.print(t1);
Serial.print(" t2: ");
Serial.println(t2);
ch3 += 8;
if(ch3 > 2400) {
ch3 = 1000;
}
delay(100);
}
As a note, you may have more Arduino/servo luck on https://robotics.stackexchange.com/.
What are you seeing on the serial output? Is ch3 cycling from 0 to 45 or from 0 to 180? Don't forget that map() is designed to do what you're doing by hand here.
My first suspicion is that you're occasionally getting 0 back from pulseIn either because you're timing out, or you're starting your reading in the middle of a pulse (which could lead to a shorter pulse than you expect).