I am using a LDR to tell me whether there is light or not with an Arduino. My code is pretty simple, but instead of spamming "light light light light" I would like it to say "light" once, and then if the light goes off, for it to say "No light" once.
code edited from "readanalogvoltage":
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:
int sensorValue = analogRead(A0);
// Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
float voltage = sensorValue * (5.0 / 1023.0);
// print out the value you read:
if (voltage > 1.5)
{
Serial.print("Light");
Serial.println();
delay(5000);
}
if (voltage < 1.5)
{
Serial.print("No Light");
Serial.println();
delay(50);
}
}
Keep a variable that holds the last state:
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
}
int wasLit = 0;
// the loop routine runs over and over again forever:
void loop() {
// read the input on analog pin 0:
int sensorValue = analogRead(A0);
// Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
float voltage = sensorValue * (5.0 / 1023.0);
// print out the value you read:
if (!wasLit && voltage > 1.5) {
wasLit = 1;
Serial.print("Light");
Serial.println();
delay(5000);
} else if(wasLit && voltage <= 1.5) {
wasLit = 0;
Serial.print("No Light");
Serial.println();
delay(50);
}
}
This sort of test will benefit from use of hysterisis. Especially if you have flourescent light, there will be some flicker. That will cause the sensor reading to vary such that it may not change from <1.5 to >=1.5 in a clean manner.
boolean bLast = false;
const float vTrip = 1.5;
// you find a good value for this by looking at the noise in readings
// use a scratch program to just read in a loop
// set this value to something much larger than any variation
const float vHyst = 0.1;
float getLight() {
int sensorValue = analogRead(A0);
// Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
float voltage = sensorValue * (5.0 / 1023.0);
return voltage;
}
void setup() {
// establish the initial state of the light
float v = getLight();
bLast = ( v < (vTrip-vHyst) );
}
void loop() {
float v = getLight();
if( bLast ) {
// light was on
// when looking for decreasing light, test the low limit
if( v < (vTrip-vHyst) ) {
bLast = false;
Serial.print("Dark");
}
}
else {
// light was off
// when looking for increasing light, test the high limit
if( v > (vTrip+vHyst) ) {
bLast = true;
Serial.print("Light");
}
}
}
Related
I am writing a program where the Arduino will start a timer using millis() when the voltage on the analogue pin A2 rises and crosses a threshold and turns off the timer when threshold is crossed again (rising voltage). It will then calculate the time = t2-t1. I thought about using external interrupt and an op-amp to detect the threshold crossing but is there anyway I can accomplish this just with code, without the need for any external hardware??? An image is attached:
Thank you for helping!
Of course:
bool is_high = false;
int threshold = 600; // (or whatever)
unsigned long start_time = 0;
void loop()
{
int val = analogRead(A2);
if (!is_high)
{
if (val > threshold) {
is_high = true;
unsigned long now = millis();
if (start_time != 0) {
Serial.print("t=");
Serial.prinln(now - start_time);
}
start_time = now;
}
}
else {
if (val < threshold) {
is_high= false;
}
}
I'm trying to run two "Blink"-esque functions simultaneously.
I've found some code elsewhere that lets me do that and modified it! Great.
However, what I am trying to do is have one LED turn on and off every 1000ms as per usual, but have the other blink in an odd pattern, like ON for 3000ms, OFF for 100ms, ON for 100ms, OFF for 200ms then loop back.
To make this happen I tried adding a random function to the code I found but I don't like how it looks. It looks like a blinking LED with interference or something, like on a radio transmitter or whatever. I'm trying to replicate an old flickering lightbulb, meaning it always has to be ON for longer than it is off, Essentially it needs to be ON/HIGH for a "longer" period of time and then interrupted by several short flashes of ON and OFF
So I'm looking for help in how I can orchestrate the 2nd LED to turn on and off in a more specific series of flickers.
Here's the code I'm using so far:
/* Blink Multiple LEDs without Delay
*
* Turns on and off several light emitting diode(LED) connected to a digital
* pin, without using the delay() function. This means that other code
* can run at the same time without being interrupted by the LED code.
*/
int led1 = 13; // LED connected to digital pin 13
int led2 = 12;
int value1 = LOW; // previous value of the LED
int value2 = HIGH; // previous value of the LED
long time1 = millis();
long time2 = millis();
long interval1 = 1000; // interval at which to blink (milliseconds)
void setup()
{
Serial.begin(9600);
randomSeed(analogRead(0));
pinMode(led1, OUTPUT); // sets the digital pin as output
pinMode(led2, OUTPUT);
}
void loop()
{
unsigned long m = millis();
if (m - time1 > interval1){
time1 = m;
if (value1 == LOW)
value1 = HIGH;
else
value1 = LOW;
digitalWrite(led1, value1);
}
long interval2 = random(100,1500);
if (m - time2 > interval2){
time2 = m;
if (value2 == LOW)
value2 = HIGH;
else
value2 = LOW;
digitalWrite(led2, value2);
}
Serial.println(interval2);
}
This will always take less than a second to run so you can get back to your main loop and ensure that you don't miss the 1 second on/off for the other LED:
void flicker(){
boolean state = false;
int r = random(20, 175);
for(int i = 0; i < 5; i++){
digitalWrite(led2, state);
state = !state;
delay(r);
r = random(20, 175);
}
digitalWrite(led2, HIGH);
}
Btw. I'm replacing this toggle code:
if (value2 == LOW)
value2 = HIGH;
else
value2 = LOW;
digitalWrite(led2, value2);
with this:
state = !state;
digitalWrite(led2, state);
Now, call flicker() at random intervals; maybe every 15-45 seconds or whatever you find appropriate/realistic.
Try something like this:
void setup()
{
Serial.begin(9600);
randomSeed(analogRead(0));
pinMode(led1, OUTPUT); // sets the digital pin as output
pinMode(led2, OUTPUT);
}
long interval2 = random(100,1500);
void loop()
{
unsigned long m = millis();
if (m - time1 > interval1){
time1 = m;
if (value1 == LOW)
value1 = HIGH;
else
value1 = LOW;
digitalWrite(led1, value1);
}
if (m - time2 > interval2){
time2 = m;
if (value2 == LOW) {
value2 = HIGH;
interval2 = random(100, 1500);
} else {
value2 = LOW;
interval2 = random(100, 200);
}
digitalWrite(led2, value2);
}
I am building a program that measure the voltage of a component (photoswitch). When the potential is under 5 V, the lamp will turn on.
But my problem is, I want the Arduino to turn on the lamp, if the voltage has been under 5 V for 10 seconds or more. For example, if the voltage level is under 5 V for 8 seconds and then it changes to over 5 V again, the lamp should not turn on.
Here is my code so far:
int Pin = 2;
const float baselineVoltage = 5.0;
void setup() {
Serial.begin(9600);
pinMode(Pin,OUTPUT);
}
void loop() {
int sensorValue = analogRead(A0);
float voltage = sensorValue * (5.0 / 1023.0);
Serial.println(voltage);
if(voltage < baselineVoltage){
digitalWrite(2,HIGH);
}
delay(10);
}
I believe something like this addresses your 10 second delay issue. If you want the same 10 second delay to turn it off, you will need to do something similar.
int Pin = 2;
const float baselineVoltage = 5.0;
int belowBaselineVoltage = false;
unsigned long turnOnAt;
const unsigned long turnOnDelay = 10 * 1000;
void setup() {
Serial.begin(9600);
pinMode(Pin, OUTPUT);
}
void loop() {
int sensorValue = analogRead(A0);
float voltage = sensorValue * (5.0 / 1023.0);
Serial.println(voltage);
if (voltage < baselineVoltage)
{
if (belowBaselineVoltage == true)
{
if (millis() >= turnOnAt)
{
digitalWrite(2, HIGH);
}
}
else
{
belowBaselineVoltage = true;
turnOnAt = millis() + turnOnDelay;
}
}
else
{
belowBaselineVoltage = false;
}
}
I have a question about arduino considering a setup with 8 leds and an potentiometer. I want to let 1 led light up, which is the led that matches the value returned by the potentiometer, and the rest of the leds should be turned off. Furthermore, when I change the position of the potentiometer, the leds should change accordingly. So far ive got this:
for(int i = 0; i)
{
if (i = draaiKnopStand)
{
status[i] = HIGH;
}
else
{
status[i] = LOW;
}
digitalWrite(draaiKnopStand, status[i]);
}
I'm considering this is Arduino Uno Front
I have no Arduino here in my job. I did this using a simulator. Please try it:
int _potentiometer = 9; // Potentiometer - Analog Pin
int _val = 0;
int _borderLineVal = 0;
int ledPins[] = { 2, 3, 4, 5, 6, 7 }; // an array of pin numbers to which LEDs are attached
int pinCount = 6; // the number of pins (i.e. the length of the array)
void setup() {
for (int thisPin = 0; thisPin < pinCount; thisPin++) {
pinMode(ledPins[thisPin], OUTPUT);
}
}
void loop() {
_val = analogRead(_potentiometer); //reading the Potentiometer value interval: 0 - 1023
_borderLineVal = (int)(1023 / pinCount);
Serial.println(_val);
// turn all leds off
for (int thisPin = 0; thisPin < pinCount; thisPin++) {
digitalWrite(ledPins[thisPin], LOW);
}
// turn the select led on
if(_val > 0){
_pinHigh = (int)(1023 / _borderLineVal);
digitalWrite(ledPins[_pinHigh], HIGH); // turn the pin on
}
}
I'm programming Arduino. I have a problem with the IR sensor. It only detects this ball (equiped with IR LEDS) in range of 0,5m and I would need at least 2m. This is the ball:
"http://drgraeme.net/drgraeme-free-nxt-g-tutorials/Ch108/SoccerGenIINXTG/Soccer%20Ball/HiTechnicRCJ05V2.jpg"
and this is my arduino code:
// digital pin 2 has a pushbutton attached to it. Give it a name:
int IR = 2;
int i = 0;
int ii = 0;
int led = 0;
void setup()
{
Serial.begin(9600);
pinMode(IR, INPUT_PULLUP);
pinMode(led, OUTPUT);
}
void loop() {
i = 0;
ii = 0;
do
{
i = i + 1;
int STANJE1 = digitalRead(IR);
if(STANJE1 < 1)
{
ii = ii + 1;
}
}while(i<1000);
if(ii > 1)
{Serial.println("IS");}
else{Serial.println("IS NOT");}
}
IR sensor is 38kHZ and the balls LEDs are 40kHZ, but I found a program that allowed me to detect the ball 10m away from sensor, but It was ment for something else, and I didn't understand it, so that is not the problem.
This is the code that works further (That's because it doesn't use "DigitalRead()")
/* Raw IR decoder sketch!
This sketch/program uses the Arduno and a PNA4602 to
decode IR received. This can be used to make a IR receiver
(by looking for a particular code)
or transmitter (by pulsing an IR LED at ~38KHz for the
durations detected
Code is public domain, check out www.ladyada.net and adafruit.com
for more tutorials!
*/
// We need to use the 'raw' pin reading methods
// because timing is very important here and the digitalRead()
// procedure is slower!
//uint8_t IRpin = 2;
// Digital pin #2 is the same as Pin D2 see
// http://arduino.cc/en/Hacking/PinMapping168 for the 'raw' pin mapping
#define IRpin_PIN PIND
#define IRpin 2
// the maximum pulse we'll listen for - 65 milliseconds is a long time
#define MAXPULSE 65000
// what our timing resolution should be, larger is better
// as its more 'precise' - but too large and you wont get
// accurate timing
#define RESOLUTION 20
// we will store up to 100 pulse pairs (this is -a lot-)
uint16_t pulses[100][2]; // pair is high and low pulse
uint8_t currentpulse = 0; // index for pulses we're storing
void setup(void) {
Serial.begin(9600);
Serial.println("Ready to decode IR!");
}
void loop(void) {
uint16_t highpulse, lowpulse; // temporary storage timing
highpulse = lowpulse = 0; // start out with no pulse length
// while (digitalRead(IRpin)) { // this is too slow!
while (IRpin_PIN & (1 << IRpin)) {
// pin is still HIGH
// count off another few microseconds
highpulse++;
delayMicroseconds(RESOLUTION);
// If the pulse is too long, we 'timed out' - either nothing
// was received or the code is finished, so print what
// we've grabbed so far, and then reset
if ((highpulse >= MAXPULSE) && (currentpulse != 0)) {
printpulses();
currentpulse=0;
return;
}
}
// we didn't time out so lets stash the reading
pulses[currentpulse][0] = highpulse;
// same as above
while (! (IRpin_PIN & _BV(IRpin))) {
// pin is still LOW
lowpulse++;
delayMicroseconds(RESOLUTION);
if ((lowpulse >= MAXPULSE) && (currentpulse != 0)) {
printpulses();
currentpulse=0;
return;
}
}
pulses[currentpulse][1] = lowpulse;
// we read one high-low pulse successfully, continue!
currentpulse++;
}
void printpulses(void) {
Serial.println("\n\r\n\rReceived: \n\rOFF \tON");
for (uint8_t i = 0; i < currentpulse; i++) {
Serial.print(pulses[i][0] * RESOLUTION, DEC);
Serial.print(" usec, ");
Serial.print(pulses[i][1] * RESOLUTION, DEC);
Serial.println(" usec");
}
}