i need to add millis in my code but i dont know exactly where should be ok to add millis or where is it acctually needed.Because i have used only delay till now can you help me and tell me where can millis be implemented in this piece of code.If it is possible to add millis somewhere in or after the button modes or switch case because it would be nicer if the modes changed properly because for now their changing either when the button is pressed normal or somtimes you need to pres the button twice to change to the next mode.I would apriciate all the help.
const int BUTTON_SWITCH = 8;
const int BUTTON_ALARM = 9;
const int KNOB = A0;
const int TEMP = A1;
const int tempRES = 10000; // the resistance of the NTC at 25'C is 10k ohm
const int NTC_MATERIAL_CONSTANT = 3950;
const int RED_LED = 4;
const int BUZZER = 3;
int index = 1;
double value;
int state = 0;
unsigned long time_now = 0;
int period = 1000;
char incomingOption;
#include "Display.h"
void setup() {
Serial.begin(9600);
pinMode(BUTTON_SWITCH, INPUT_PULLUP);
pinMode(BUTTON_ALARM, INPUT_PULLUP);
pinMode(RED_LED, OUTPUT);
}
float get_temperature()
{
float temperature, resistance;
int value;
value = analogRead(TEMP);
resistance = (float)value * tempRES / (1024 - value); // Calculate resistance
/* Calculate the temperature according to the following formula. */
temperature = 1 / (log(resistance / tempRES) / NTC_MATERIAL_CONSTANT + 1 / 298.15) - 273.15;
return temperature;
}
void loop() {
if (digitalRead(BUTTON_SWITCH) == LOW) { // button for switching the 3 modes
index = index + 1;
}
if (digitalRead(BUTTON_ALARM) == LOW) { // button for the alarm
displayAlarm();
}
if (Serial.available()) {
// Read entire buffer up to newline character
// Since on the C# side, serialPort1.WriteLine appends a newline character
String respond = Serial.readStringUntil('\n');
if (respond == "RESET") {
digitalWrite(RED_LED, LOW);
digitalWrite(BUZZER, LOW);
}
}
if (index > 3) { // when the code is on the last mode press the button to turn back to the first mode
index = 1;
}
get_temperature();
float celcius;
celcius = get_temperature();
if(celcius<16 || celcius>27){ // if the temperature becomes less than 16 degrees or goes higher than 27 degrees turn on the alarm
displayAlarm();
}
switch (index) {
case 1: displayTime(); break; // switch between the 3 different modes
case 2: displayTemp(); break;
case 3: displayAngle(); break;
}
}
void displayTime() {
float timer = Serial.parseFloat(); // take the current time from the c# application and display it on the arduino board
Display.show(timer);
}
void displayTemp() {
float celcius;
celcius = get_temperature(); // mode for displaying the current temperature
Display.show(celcius);
}
void displayAngle() {
int value = analogRead(KNOB); // read and save analog value from the potentionmeter
value = map(value, 0, 1023, 0, 30); // Map value 0-1023 to 0-30
Display.show(value);
}
void displayAlarm() {
Serial.println("Alarm");
digitalWrite(RED_LED, HIGH);
tone(BUZZER, 1500, 700);
}
I'm using a SG-90 servo and sweeping left and right between two values.
My problem is that there is a distinct delay of about 500ms between direction changes. I would like the position of the servo to be predictable, but due to this at direction changes it is not.
bool servoDir = true;
int servoCnt = 90;
int servoInc = 1;
int servoMin = servoCnt - 5;
int servoMax = servoCnt + 5;
void loop() {
if (servoDir) {
dx = servoInc;
if (servoCnt > servoMax) {
servoDir = false;
}
} else {
dx = -servoInc;
if (servoCnt < servoMin) {
servoDir = true;
}
}
servoCnt += dx;
servo.write(servoCnt);
// delay or other code here (mine is 40ms)
}
I've tried both the Arduino Servo library and the VarspeedServo library. They both show the same thing.
What is the cause of this and what can I do about it?
Update
So if I up the speed at direction change, like so:
int extra = 5;
void loop() {
if (servoDir) {
dx = servoInc;
if (servoCnt > servoMax) {
dx -= extra;
servoDir = false;
}
} else {
dx = -servoInc;
if (servoCnt < servoMin) {
dx += extra;
servoDir = true;
}
}
servoCnt += dx;
servo.write(servoCnt);
// delay or other code here (mine is 40ms)
}
the delay disappears, but the servo position does become a lot less predictable.
You would experience exactly these symptoms if servoMin and servoMax were out of the servo range.... Which they are.
More seriously, these servos are not very precise. Incrementing by 1 at a time is probably the issue. You are experiencing some form of backlash.
You should check and clamp the count against the range AFTER incrementing/decrementing. That's one of the basic rules of embedded programming. Lives may be at stake, or equipment destroyed when sending out out of range values.
bool servoDir = true;
int servoCnt = 90;
int servoInc = 1; // <-- exclusively use this to control speed.
int servoMin = servoCnt - 5; // <-- this range is a bit short for testing
int servoMax = servoCnt + 5;
void loop() {
// 'jog' the servo.
servoCnt += (servoDir) ? servoInc : -servoInc;
// past this point, all position jogging is final
if (servoCnt > servoMax)
{
servoCnt = servoMax;
servoDir = false;
}
else if (servoCnt < servoMin)
{
servoCnt = servoMin;
servoDir = true;
}
servo.write(servoCnt);
// 40ms sounds a bit short for tests.
// 100 ms should give you a 2 seconds (0.5Hz) oscillation
delay(100);
}
I wanted to move my BLDC motor using a timer interrupt. Somehow, the motor would not spin at all. I want the motor to spin according to the RPM set in the code. I was wondering if you guys can pin point my mistakes. Here is the code:
#include <Wire.h> // Comes with Arduin
#define POSITIVE 1
int timerPin = 11;
int timer1_counter;
int prescaler;
// STATE CONDITION FOR MAIN LOOP
enum { enter_values, spin , finish } systemstate;
unsigned long previousMillis = 0;
// RPM MEASUREMENT
const int dataIN = 2; //IR sensor INPUT
unsigned long prevmillis; // To store time
unsigned long duration; // To store time difference
unsigned long lcdrefresh; // To store time for lcd to refresh
int rpm; // RPM value
boolean currentstate; // Current state of IR input scan
boolean prevstate; // State of IR sensor in previous scan
// DECLARE
int stage1speed , stage1time , stage2speed , stage2time , stage3speed , stage3time ;
void setup()
{
Serial.begin(9600);
systemstate = enter_values; // set up the starting state
pinMode(dataIN, INPUT);
prevmillis = 0;
prevstate = LOW;
pinMode (timerPin, OUTPUT);
//rmc timer interrupt
// initialize timer1
noInterrupts(); // disable all interrupts
TCCR1A = 0;
TCCR1B = 0;
// Set timer1_counter to the correct value for our interrupt interval
//timer1_counter = 64911; // preload timer 65536-16MHz/256/100Hz
//timer1_counter = 64286; // preload timer 65536-16MHz/256/50Hz
//timer1_counter = 34286; // preload timer 65536-16MHz/256/2Hz
timer1_counter = 65536 - F_CPU/256/2;
prescaler = 8;
TCNT1 = timer1_counter; // preload timer
TCCR1B |= (1 << CS11) | (0 << CS10); // prescaler
TIMSK1 |= (1 << TOIE1); // enable timer overflow interrupt
interrupts(); // enable all interrupts
}
ISR(TIMER1_OVF_vect) // interrupt service routine
{
static byte outp = 0;
TCNT1 = timer1_counter; // preload timer
digitalWrite(timerPin, outp);
outp = 1-outp;
}
//FUNCTION FOR KEY IN SPEED AND TIME
void enter_speed_time()
{
stage1speed = 4000;
stage1time = 10;
stage2speed = 6000;
stage2time = 10;
stage3speed = 8000;
stage3time = 10;
return;
}
// FUNCTION FOR RPM MEASUREMENT
void rpmMeasure()
{
static long last_update;
// RPM Measurement
currentstate = digitalRead(dataIN); // Read IR sensor state
if ( prevstate != currentstate) // If there is change in input
{
if ( currentstate == HIGH ) // If input only changes from LOW to HIGH
{
duration = ( micros() - prevmillis ); // Time difference between revolution in microsecond
rpm = (60000000 / duration); // rpm = (1/ time millis)*1000*1000*60;
prevmillis = micros(); // store time for next revolution calculation
}
}
prevstate = currentstate; // store this scan (prev scan) data for next scan
if (millis()-last_update > 1000)
{
Serial.print ("speed=");
Serial.println (rpm);
last_update = millis();
}
}
void set_speed (int speed)
{
Serial.print ("set speed=");
Serial.println (speed);
timer1_counter = 65536 - F_CPU/prescaler/speed*60/2;
//myservo.write(speed);
}
// FUNCTION FOR MOTOR SPINNING ACCORDING TO TIME AND SPEED
void motorspin()
{
unsigned long currentMillis = millis();
int idleValue = 0;
static enum { IDLE, STAGE1, STAGE2, STAGE3 } spinningstate;
switch (spinningstate) {
case IDLE:
set_speed(stage1speed);
previousMillis = currentMillis;
spinningstate = STAGE1;
break;
case STAGE1:
if (currentMillis - previousMillis >= stage1time * 1000) {
set_speed(stage2speed);
previousMillis = currentMillis;
spinningstate = STAGE2;
}
break;
case STAGE2:
if (currentMillis - previousMillis >= stage2time * 1000) {
set_speed(stage3speed);
previousMillis = currentMillis;
spinningstate = STAGE3;
}
break;
case STAGE3:
if (currentMillis - previousMillis >= stage3time * 1000) {
set_speed(idleValue);
spinningstate = IDLE;
}
break;
}
}
// MAIN LOOP
void loop()
{
switch (systemstate)
{
case enter_values:
enter_speed_time();
systemstate = spin;
break;
case spin:
rpmMeasure();
motorspin();
if (0) // haven't figure out yet
{
systemstate = finish;
}
break;
case finish:
systemstate = enter_values;
break;
}
}
I'm trying to read how many times a switch is clicked in 60 seconds in arduino. Referring to the documentation,I have implemented a countdown timer that counts down from 60s to 0. The button state is only being checked only one time per second. If I push the button more than one time per second, it registers as only one. What am I doing wrong?
Here's the code :
const int buttonPin = 2;
unsigned int Clock = 0, R_clock;
boolean Reset = false, Stop = false, Paused = false;
volatile boolean timeFlag = false;
int buttonPushCounter = 0; // counter for the number of button presses
int buttonState = 0; // current state of the button
int lastButtonState = 0; // previous state of the button
void setup() {
// initialize the button pin as a input:
pinMode(buttonPin, INPUT);
Serial.begin(9600);
SetTimer(0,0,60); // 10 seconds
StartTimer();
}
void loop() {
CountDownTimer(); // run the timer
if (TimeHasChanged() )
{
Serial.print(ShowSeconds());
Serial.println();
}
}
void StartTimer()
{
Watch = micros(); // get the initial microseconds at the start of the timer
Stop = false;
}
boolean CountDownTimer()
{
static unsigned long duration = 1000000; // 1 second
timeFlag = false;
if (!Stop && !Paused) // if not Stopped or Paused, run timer
{
if ((_micro = micros()) - time > duration )
{
Clock--;
timeFlag = true;
if (Clock == 0) // check to see if the clock is 0
Stop = true; // If so, stop the timer
if(ShowSeconds()>0 && ShowSeconds() <= 60){
buttonState = digitalRead(buttonPin);
// compare the buttonState to its previous state
if (buttonState != lastButtonState) {
buttonState = digitalRead(buttonPin);
// compare the buttonState to its previous state
if (buttonState != lastButtonState) {
// if the state has changed, increment the counter
if (buttonState == HIGH) {
// if the current state is HIGH then the button
// wend from off to on:
buttonPushCounter++;
Serial.println("on");
Serial.print("number of button pushes: ");
Serial.println(buttonPushCounter);
} else {
// if the current state is LOW then the button
// wend from on to off:
Serial.println("off");
}
}
}
}}
}
return !Stop; // return the state of the timer
}
void SetTimer(unsigned int hours, unsigned int minutes, unsigned int seconds)
{
// This handles invalid time overflow ie 1(H), 0(M), 120(S) -> 1, 2, 0
unsigned int _S = (seconds / 60), _M = (minutes / 60);
if(_S) minutes += _S;
if(_M) hours += _M;
Clock = (hours * 3600) + (minutes * 60) + (seconds % 60);
R_clock = Clock;
Stop = false;
}
void SetTimer(unsigned int seconds)
{
// StartTimer(seconds / 3600, (seconds / 3600) / 60, seconds % 60);
Clock = seconds;
R_clock = Clock;
Stop = false;
}
int ShowSeconds()
{
return Clock % 60;
}
boolean TimeHasChanged()
{
return timeFlag;
}
The code written is basically for edge state detection. That was the primary reason why the button state was not being read in other time intervals.
I'm a newbie when it comes to electronics and Arduino - so the best way is to just to play around with it, right?
I have started a small project that utilize and LDR (Light Density Resistor) and want to use it to calculate the frequency that a light beam is blocked or turned off.
For debugging purposes I setup a small LED that blinks at a defined frequency (5 Hz etc.) and use a LCD to display the output.
I have a problem with my top right corner... It seems as it performs wrongly. It was the intention that it should show the registered frequency, but while debugging I have set it to show the number of counts in an interval of 5 sec (5,000 msec). But it appears as 24 is the max no matter what frequency I set (When I get it to show the right number [5 sec x 5 Hz = 25] I will divide by the time interval and get the results in Hz). It also shows 24.0 for 9 Hz etc..
I also have this: YouTube video
...but some fumbling in the beginning caused the LED to move a bit so it counted wrong. But in the end it "works".. But the 24.0 keeps being constant
This is my code:
#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 8, 9, 10, 11 , 12);
int booBlocked = 0;
int counter = 0;
int checkValue = counter + 1;
int ledPin = 3; // LED connected to digital pin 3
int value = LOW; // previous value of the LED
long previousMillis = 0; // will store last time LED was updated
long freqency = 5; // Hz (1/sec)
long thousand = 1000;
long interval = thousand / freqency; // milliseconds
//long interval = 59; // interval at which to blink (milliseconds)
int tValue = 0; // Threshold value used for counting (are calibrated in the beginning)
long pMillis = 0;
long inter = 5000;
int pCount = 0;
float freq = 0; // Calculated blink frequency...
void setup() {
lcd.begin(16, 2);
lcd.setCursor(0,1); lcd.print(interval);
lcd.setCursor(4,1); lcd.print("ms");
pinMode(ledPin, OUTPUT); // sets the digital pin as output
lcd.setCursor(0,0); lcd.print(freqency);
lcd.setCursor(4,0); lcd.print("Hz");
}
void loop() {
// Print LDR sensor value to the display
int sensorValue = analogRead(A0);
lcd.setCursor(7,1);
lcd.print(sensorValue);
delay(100);
if (millis() > 5000){
doCount(sensorValue);
updateFreq();
lcd.setCursor(7+5,0);
lcd.print(freq);
} else {
setThresholdValue(sensorValue);
lcd.setCursor(7+5,1);
lcd.print(tValue);
}
// LED BLINK
if (millis() - previousMillis > interval) {
previousMillis = millis(); // remember the last time we blinked the LED
// if the LED is off turn it on and vice-versa.
if (value == LOW)
value = HIGH;
else
value = LOW;
digitalWrite(ledPin, value);
}
}
void updateFreq(){
long now = millis();
long t = now - pMillis;
if (t >= 10000) {
freq = (float) (counter - pCount);
//freq = ((float) (counter - pCount)) / (float) 10.0;
pMillis = now; // remember the last time we blinked the LED
pCount = counter;
}
}
void setThresholdValue(int sensorValue){
if (sensorValue > int(tValue/0.90)){
tValue = int (sensorValue*0.90);
}
}
void doCount(int sensorValue){
// Count stuff
if (sensorValue < tValue){
booBlocked = 1;
//lcd.setCursor(0,0);
//lcd.print("Blocked");
} else {
booBlocked = 0;
//lcd.setCursor(0,0);
//lcd.print(" ");
}
if (booBlocked == 1) {
if (counter != checkValue){
counter = counter + 1;
lcd.setCursor(7,0);
lcd.print(counter);
}
} else {
if (counter == checkValue){
checkValue = checkValue + 1;
}
}
}
UPDATE
A more "clean" code (please see my own answer)
#include <LiquidCrystal.h>
// Initiate the LCD display
LiquidCrystal lcd(7, 8, 9, 10, 11 , 12); // see setup at http://lassenorfeldt.weebly.com/1/post/2013/02/ardunio-lcd.html
long updateInterval = 150; // ms
long updateTime = 0;
// Declare the pins
int ledPin = 3; // LED connected to digital pin 3
// LED setup
int value = LOW; // previous value of the LED
long previousMillis = 0; // will store last time LED was updated
long freqency = 16; // Hz (1/sec)
long thousand = 1000;
long blinkInterval = thousand / freqency; // milliseconds
//// LDR counter variables ////
// Counting vars
static int counter = 0;
int booBlocked = 0;
int checkValue = counter + 1;
// Calibration vars
long onBootCalibrationTime = 5000; // time [time] to use for calibration when the system is booted
static int threshold = 0; // Value used for counting (calibrated in the beginning)
float cutValue = 0.90; // Procent value used to allow jitting in the max signal without counting.
// Frequency vars
float freq = 0; // Calculated blink frequency...
long frequencyInterval = 5000; // time [ms]
long pMillis = 0;
int pCount = 0;
void setup() {
// Setup the pins
pinMode(ledPin, OUTPUT); // sets the digital pin as output
// display static values
lcd.begin(16, 2);
lcd.setCursor(0,0); lcd.print(freqency);
lcd.setCursor(4,0); lcd.print("Hz");
lcd.setCursor(0,1); lcd.print(blinkInterval);
lcd.setCursor(4,1); lcd.print("ms");
// Setup that allows loggin
Serial.begin(9600); // Allows to get a readout from Putty (windows 7)
}
void loop() {
long time = millis();
int sensorValue = analogRead(A0);
// Blink the LED
blinkLED(time);
// Calibrate or Count (AND calculate the frequency) via the LDR
if (time < onBootCalibrationTime){
setThresholdValue(sensorValue);
} else {
doCount(sensorValue);
updateFreq(time);
}
// Update the LCD
if (time > updateTime){
updateTime += updateInterval; // set the next time to update the LCD
// Display the sensor value
lcd.setCursor(7,1); lcd.print(sensorValue);
// Display the threshold value used to determined if blocked or not
lcd.setCursor(7+5,1); lcd.print(threshold);
// Display the count
lcd.setCursor(7,0);
lcd.print(counter);
// Display the calculated frequency
lcd.setCursor(7+5,0); lcd.print(freq);
}
}
void blinkLED(long t){
if (t - previousMillis > blinkInterval) {
previousMillis = t; // remember the last time we blinked the LED
// if the LED is off turn it on and vice-versa.
if (value == LOW)
value = HIGH;
else
value = LOW;
digitalWrite(ledPin, value);
}
}
void setThresholdValue(int sValue){
if (sValue > int(threshold/cutValue)){
threshold = int (sValue*cutValue);
}
}
void doCount(int sValue){
if (sValue < threshold){
booBlocked = 1;
} else {
booBlocked = 0;
}
if (booBlocked == 1) {
if (counter != checkValue){
counter = counter + 1;
}
} else {
if (counter == checkValue){
checkValue = checkValue + 1;
}
}
}
void updateFreq(long t){
long inter = t - pMillis;
if (inter >= frequencyInterval) {
freq = (counter - pCount) / (float) (inter/1000);
pMillis = t; // remember the last time we blinked the LED
pCount = counter;
}
}
This code does not fix my question, but is just more easy to read.
The issue with your plan is that a light density resistor is going to pick up all the ambient light around and therefore be completely environment sensitive.
Have any other project hopes? This one seems like an engineering learning experience, not a coding one.
Have you thought of motor projects? Personally I'm more into home automation, but motor projects are almost instantly rewarding.
I'd recommend to re-write your doCount() function along these lines to make things simpler and easier to grasp:
void doCount(int sensorValue){
static int previousState;
int currentState;
if ( previousState == 0 ) {
currentState = sensorValue > upperThreshold;
} else {
currentState = sensorValue > lowerThreshold;
}
if ( previousState != 0 ) {
if ( currentState == 0 ) {
counter++;
}
}
previousState = currentState;
}
Let lowerThreshold and upperThreshold be, for example, 90% and 110%, respectively, of your former tValue, and you have a hysteresis to smoothen the reaction to noisy ADC read-outs.
I think i found one of the bugs.. I was using a delay() which caused some trouble..
I cleaned up the code:
#include <LiquidCrystal.h>
// Initiate the LCD display
LiquidCrystal lcd(7, 8, 9, 10, 11 , 12); // see setup at http://lassenorfeldt.weebly.com/1/post/2013/02/ardunio-lcd.html
long updateInterval = 150; // ms
long updateTime = 0;
// Declare the pins
int ledPin = 3; // LED connected to digital pin 3
// LED setup
int value = LOW; // previous value of the LED
long previousMillis = 0; // will store last time LED was updated
long freqency = 16; // Hz (1/sec)
long thousand = 1000;
long blinkInterval = thousand / freqency; // milliseconds
//// LDR counter variables ////
// Counting vars
static int counter = 0;
int booBlocked = 0;
int checkValue = counter + 1;
// Calibration vars
long onBootCalibrationTime = 5000; // time [time] to use for calibration when the system is booted
static int threshold = 0; // Value used for counting (calibrated in the beginning)
float cutValue = 0.90; // Procent value used to allow jitting in the max signal without counting.
// Frequency vars
float freq = 0; // Calculated blink frequency...
long frequencyInterval = 5000; // time [ms]
long pMillis = 0;
int pCount = 0;
void setup() {
// Setup the pins
pinMode(ledPin, OUTPUT); // sets the digital pin as output
// display static values
lcd.begin(16, 2);
lcd.setCursor(0,0); lcd.print(freqency);
lcd.setCursor(4,0); lcd.print("Hz");
lcd.setCursor(0,1); lcd.print(blinkInterval);
lcd.setCursor(4,1); lcd.print("ms");
// Setup that allows loggin
Serial.begin(9600); // Allows to get a readout from Putty (windows 7)
}
void loop() {
long time = millis();
int sensorValue = analogRead(A0);
// Blink the LED
blinkLED(time);
// Calibrate or Count (AND calculate the frequency) via the LDR
if (time < onBootCalibrationTime){
setThresholdValue(sensorValue);
} else {
doCount(sensorValue);
updateFreq(time);
}
// Update the LCD
if (time > updateTime){
updateTime += updateInterval; // set the next time to update the LCD
// Display the sensor value
lcd.setCursor(7,1); lcd.print(sensorValue);
// Display the threshold value used to determined if blocked or not
lcd.setCursor(7+5,1); lcd.print(threshold);
// Display the count
lcd.setCursor(7,0);
lcd.print(counter);
// Display the calculated frequency
lcd.setCursor(7+5,0); lcd.print(freq);
}
}
void blinkLED(long t){
if (t - previousMillis > blinkInterval) {
previousMillis = t; // remember the last time we blinked the LED
// if the LED is off turn it on and vice-versa.
if (value == LOW)
value = HIGH;
else
value = LOW;
digitalWrite(ledPin, value);
}
}
void setThresholdValue(int sValue){
if (sValue > int(threshold/cutValue)){
threshold = int (sValue*cutValue);
}
}
void doCount(int sValue){
if (sValue < threshold){
booBlocked = 1;
} else {
booBlocked = 0;
}
if (booBlocked == 1) {
if (counter != checkValue){
counter = counter + 1;
}
} else {
if (counter == checkValue){
checkValue = checkValue + 1;
}
}
}
void updateFreq(long t){
long inter = t - pMillis;
if (inter >= frequencyInterval) {
freq = (counter - pCount) / (float) (inter/1000);
pMillis = t; // remember the last time we blinked the LED
pCount = counter;
}
}
Its not as precise as I wished.. but I believe that this is might due to the way I blink the LED.
I also discovered that float cutValue = 0.90; has an influence... lowering the bar to 0.85 decrease the calculated frequency.. ??
I changed the code completely after Albert was so kind to help me out using his awesome FreqPeriodCounter library
I also added a potentiometer to control the frequency
Here is my code:
#include <FreqPeriodCounter.h>
#include <LiquidCrystal.h>
// FrequencyCounter vars
const byte counterPin = 3; // Pin connected to the LDR
const byte counterInterrupt = 1; // = pin 3
FreqPeriodCounter counter(counterPin, micros, 0);
// LCD vars
LiquidCrystal lcd(7, 8, 9, 10, 11 , 12); // see setup at http://lassenorfeldt.weebly.com/1/post/2013/02/ardunio-lcd.html
long updateInterval = 200; // ms
long updateTime = 0;
// LED vars
int ledPin = 5; // LED connected to digital pin 3
int value = LOW; // previous value of the LED
float previousMillis = 0; // will store last time LED was updated
static float freqency; // Hz (1/sec)
static float pfreqency;
static float blinkInterval; // milliseconds
boolean logging = true; // Logging by sending to serial
// Use potentiometer to control LED frequency
int potPin = 5; // select the input pin for the potentiometer
int val = 0; // variable to store the value coming from the sensor
void setup(void){
// Setup the pins
pinMode(ledPin, OUTPUT); // sets the digital pin as output
val = analogRead(potPin);
freqency = map(val, 0, 1023, 0, 25); // Hz (1/sec)
pfreqency = freqency;
blinkInterval = 1000 / (freqency*2); // milliseconds
// LCD display static values
lcd.begin(16, 2);
lcd.setCursor(0,0); lcd.print(freqency);
lcd.setCursor(4,0); lcd.print("Hz");
lcd.setCursor(14,0); lcd.print("Hz");
lcd.setCursor(0,1); lcd.print(blinkInterval);
lcd.setCursor(4,1); lcd.print("ms");
//
attachInterrupt(counterInterrupt, counterISR, CHANGE);
// Logging
if (logging) {Serial.begin(9600);}
}
void loop(void){
// Loop vars
float time = (float) millis();
float freq = (float) counter.hertz(10)/10.0;
// Blink the LED
blinkLED(time);
if (logging) {
if(counter.ready()) Serial.println(counter.hertz(100));
}
// Update the LCD
if (time > updateTime){
updateTime += updateInterval; // set the next time to update the LCD
lcdNicePrint(7+3, 0, freq); lcd.setCursor(14,0); lcd.print("Hz");
val = analogRead(potPin);
freqency = map(val, 0, 1023, 1, 30);
if (freqency != pfreqency){
pfreqency = freqency;
blinkInterval = 1000 / (freqency*2); // milliseconds
lcdNicePrint(0,0, freqency); lcd.setCursor(4,0); lcd.print("Hz");
lcd.setCursor(0,1); lcd.print(blinkInterval);
lcd.setCursor(4,1); lcd.print("ms");
}
}
}
void lcdNicePrint(int column, int row, float value){
lcd.setCursor(column, row); lcd.print("00");
if (value < 10) {lcd.setCursor(column+1, row); lcd.print(value);}
else {lcd.setCursor(column, row); lcd.print(value);}
}
void blinkLED(long t){
if (t - previousMillis > blinkInterval) {
previousMillis = t; // remember the last time we blinked the LED
// if the LED is off turn it on and vice-versa.
if (value == LOW)
value = HIGH;
else
value = LOW;
digitalWrite(ledPin, value);
}
}
void counterISR()
{ counter.poll();
}