Arduino MultiTimer - arduino

Newbie here.
I want to delay-off 5 sets of LEDs each set has 1 main push button to turn on the LED and 2 push buttons for increase or decrease its delay-off value.
Power On:
All LEDs off
All timers value min. value is 0
All timers are delay-off
function:
When T1 has pressed the delay off value increments by 10
When button (1) was pressed D1 will on and turns off after delay-off
the value was achieved.
Same functionality with other LEDs.
Consideration:
each sets are independent to each other which means if timer 1 has 1 sec delay-off timer 2 can be set to 3secs.
Panel Board
I search on many libraries, but I'm having difficulty on what to use.
I have my code, and I'm having the problem changing the timer value.
Here's my code--------------------------------------------------------------
#include <Arduino.h>
#include <Timer.h>
const int LED1 = 5;
const int LED2 = 11;
int btn = 6;
int addV = 7; //connect another LED to this pin (don't forget the resistor)
const unsigned long PERIOD1 = 1000; //one second
int unsigned long PERIODsum; //ten seconds
Timer t; //instantiate the timer object
void setup(void)
{
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(btn, INPUT_PULLUP);
pinMode(addV, INPUT_PULLUP);
t.oscillate(LED1, PERIOD1, HIGH);
t.oscillate(LED2, PERIODsum, HIGH);
Serial.begin(9600);
}
int addVf(){
PERIODsum += 10;
return(PERIODsum);
}
void loop(void)
{
int addVon = digitalRead(addV);
if(!addVon){
addVf();
}
int btnS = digitalRead(btn);
if(!btnS){
t.update();
Serial.println("Loop Value: ");
Serial.println(PERIODsum);
}
}

Attached a tiny bit of code which works for 3 channels like you need.
Without any additional libraries needed.
The loop function calls funtions to check buttons and timer value and do then a 50ms delay.
What you have still to add is an press/realease function for start, increase and decrese button press. Else every loop (50ms) the buttons will detected as pressed. What mean the value of settime will increased all time.
//timing defines
#define INC_STEP 20
#define DEC_STEP 20
#define LOOP_DELAY 50
//input/output defines
#define BTN_CH_A_Start 6
#define BTN_CH_A_Inc 7
#define BTN_CH_A_Dec 8
#define LED_PIN_CH_A 9
unsigned int SetTime_CH_A = 0;
unsigned int DelayTimer_CH_A = 0;
#define BTN_CH_B_Start 10
#define BTN_CH_B_Inc 11
#define BTN_CH_B_Dec 12
#define LED_PIN_CH_B 13
unsigned int SetTime_CH_B = 0;
unsigned int DelayTimer_CH_B = 0;
#define BTN_CH_C_Start 14
#define BTN_CH_C_Inc 15
#define BTN_CH_C_Dec 16
#define LED_PIN_CH_C 17
unsigned int SetTime_CH_C = 0;
unsigned int DelayTimer_CH_C = 0;
void setup() {
Serial.begin(9600);
pinMode(BTN_CH_A_Start, INPUT_PULLUP);
pinMode(BTN_CH_A_Inc, INPUT_PULLUP);
pinMode(BTN_CH_A_Dec, INPUT_PULLUP);
pinMode(LED_PIN_CH_A, OUTPUT);
pinMode(BTN_CH_B_Start, INPUT_PULLUP);
pinMode(BTN_CH_B_Inc, INPUT_PULLUP);
pinMode(BTN_CH_B_Dec, INPUT_PULLUP);
pinMode(LED_PIN_CH_B, OUTPUT);
pinMode(BTN_CH_C_Start, INPUT_PULLUP);
pinMode(BTN_CH_C_Inc, INPUT_PULLUP);
pinMode(BTN_CH_C_Dec, INPUT_PULLUP);
pinMode(LED_PIN_CH_C, OUTPUT);
}
void CheckButtons()
{
//check if the delay timer value have to set to inital value
if (digitalRead(BTN_CH_A_Start)) DelayTimer_CH_A = SetTime_CH_A;
if (digitalRead(BTN_CH_B_Start)) DelayTimer_CH_B = SetTime_CH_B;
if (digitalRead(BTN_CH_C_Start)) DelayTimer_CH_C = SetTime_CH_C;
//check if SetTime value have to increase
if (digitalRead(BTN_CH_A_Inc)) SetTime_CH_A += INC_STEP;
if (digitalRead(BTN_CH_B_Inc)) SetTime_CH_B += INC_STEP;
if (digitalRead(BTN_CH_C_Inc)) SetTime_CH_C += INC_STEP;
//check if SetTime value have to decrease
//if button pressed check if decrease if greater 0 decrese by DEC_STEP. if not set to 0
if (digitalRead(BTN_CH_A_Dec)) if (SetTime_CH_A-DEC_STEP>=0) SetTime_CH_A -= DEC_STEP; else SetTime_CH_A=0;
if (digitalRead(BTN_CH_B_Dec)) if (SetTime_CH_B-DEC_STEP>=0) SetTime_CH_B -= DEC_STEP; else SetTime_CH_B=0;
if (digitalRead(BTN_CH_C_Dec)) if (SetTime_CH_C-DEC_STEP>=0) SetTime_CH_C -= DEC_STEP; else SetTime_CH_C=0;
}
void CheckDelayTimer()
{
//check the actual value of DelayTimer decrase if greater than 0 drectese an the output high else set output low
if (DelayTimer_CH_A>0) { DelayTimer_CH_A--; digitalWrite(LED_PIN_CH_A, 1); } else digitalWrite(LED_PIN_CH_A, 0);
if (DelayTimer_CH_B>0) { DelayTimer_CH_B--; digitalWrite(LED_PIN_CH_B, 1); } else digitalWrite(LED_PIN_CH_B, 0);
if (DelayTimer_CH_C>0) { DelayTimer_CH_C--; digitalWrite(LED_PIN_CH_C, 1); } else digitalWrite(LED_PIN_CH_C, 0);
}
void loop() {
CheckButtons();
CheckDelayTimer();
delay(LOOP_DELAY);
}

Related

speed,time,cycle and direction stepper motor by arduino

I want my stepper motor to run at a specified speed for a specified time and stop for a set time and then repeat the same cycle.
In fact, the number of times the user has to do this will determine the user
I have the last code that failed, but this is not working properly for more than 30 seconds and the steppper motor rotates permanently.
#include <Stepper.h>
const int stepPin = 6; //PUL -Pulse
const int stepsPerRevolution = 1600;
const int dirPin = 7; //DIR -Direction
const int enPin = 8; //ENA -Enable
int one = 30000;//user input
int c = 2;// user input
int rpm = 1200;//user input
unsigned long t = 0;
Stepper myStepper(stepsPerRevolution, 6, 7);
void setup() {
Serial.begin(9600);
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
pinMode(enPin, OUTPUT);
digitalWrite(enPin, LOW);
myStepper.setSpeed(rpm);
}
void loop() {
Cycle();
digitalWrite(enPin, HIGH);
}
void Cycle() {
int cycle = 1;
for (cycle ; cycle <= c; cycle++) {
t = millis();
while ((millis() - t) < one) {
myStepper.step(stepsPerRevolution);//counter clockwise rotation
}
delay(3000);
}
}
int one = 30000;//user input
If you're going to use an int as your timing variable, then you need to look up what is the maximum value that an int can hold on your particular board. If you're using something like an UNO or a Mega then that's 32767 and that will probably explain why it doesn't work with anything over about 32 seconds.

How do I receive a HIGH or LOW signal from an IR sensor on an Arduino?

I'm trying to use an IR sensor with my Arduino Uno and only want a HIGH or LOW signal without decoding making any IR signal turn the state to a 1 or 0. There is also a motion sensor but that code has been removed.
int ledPin = 13; // choose the pin for the LED
int inputPin = 2; // choose the input pin (for PIR sensor)
int pirState = LOW; // we start, assuming no motion detected
int val = 0; // variable for reading the pin status
int relayPin = 4; //PIN FOR RELAY OPERATION
int irPin = 7; //IR Sensor pin
int lightState = 0;
int irVal = 0;
void setup() {
pinMode(ledPin, OUTPUT); // declare LED as output
pinMode(inputPin, INPUT); // declare sensor as input
pinMode(relayPin, OUTPUT);
pinMode(irPin, INPUT);
Serial.begin(9600);
}
void loop() {
irVal = digitalRead(irPin);
if (irVal == HIGH) {
lightState = 1;
Serial.println("IR received");
while(irVal == HIGH) {
irVal = digitalRead(irPin);
if(irVal == HIGH) {
irVal = LOW;
} else {
irVal = HIGH;
}
}
}
Are you trying to say that the input is not working correctly? Maybe try INPUT_PULLUP instead of INPUT in the setup loop.
For example:
pinMode(inputPin, INPUT_PULLUP);
Information about this principle you can find here:
https://www.arduino.cc/en/Tutorial/InputPullupSerial

Arduino Interrupt misbehaving

I'm having some problems with some C code I'm writing for an arduino project. The goal is to digitize a large quantity of analog signals with external multiplexed ADCs, then load these digital values into an external shift register and shift them into the Arduino using SPI.To test my code I only have one ADC multiplexing 4 signals.
The interrupt pin (20) is connected to a comparator circuit which looks at the raw analog signal and pulls the pin high when the voltage is 1V or higher. When the ISR is called it will disable global interrupts "noInterrupts()" set an event flag, detach pin 20 from the interrupt handler, enable global interrupts "interrupts()" and finally return to where it left off.
I'm facing a couple issues, first the ISR is called once fine, a second time fine but after the second ISR call it is not called again untill, which is my seconds issue, the interrupt pin goes low. As per the AttachInterupt() function the ISR should only be called when pin 20 is high. This can be seen in the first and second picture I have attached. Another thing I notice is that the duration that the interrupt pin is high has no effect on whether a 3rd ISR is called.
I'm not sure if this is an issue with my understanding of the interrupt-handling of the Arduino, or a code screw up resulting in a stack overflow or something like that.
// the sensor communicates using SPI, so include the library:
#include <SPI.h>
//Constants
#define RD 41 //pin 41 conneced to read pin
#define INT1 37 //pin 37 connecte to interrupt 1
#define CLK_INH 53 //pin 53 connected to clk inhibit
#define LD 40 //pin 40 connected to load pin
#define INPUT_MAX 3 //input selector limit (Zero Indexed)
#define SENSORS 3 //how many sensors are used (Zero Indexed)
#define DATA_DUMP 38 //pin 29 controlls the data dump deature
#define BYTE_LEN 1 //number of ADC used
#define DEBUG1 17
#define DEBUG2 16
//Controls
unsigned char selector = 0; //ACD input selector
volatile byte eventFlag = LOW; //Control Flag, set to True when event occurs
bool lastButtonState = true;
//Counters
unsigned int i = 0; //eventLog[i]: event counter
unsigned int j = 0; //eventLog[i].data[j]: data counter
//Function Delcarations
unsigned char inputSelector (unsigned char my_selector);
void lockAndPop ();
void dataDump ();
void debug (int pin);
bool fallingEdge (bool); //check for a falling edge of a digital read
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup() {
// put your setup code here, to run once:
pinMode(RD, OUTPUT); //Read pin, 0 = begin analog conversion (ADC)
pinMode(INT1, INPUT); //Interrupt pin, 0 = conversion complete (ADC)
pinMode(CLK_INH, OUTPUT); //Clock inhibit pin, 1= no change on output (ShiftRegister)
pinMode(LD, OUTPUT); //Shift/Load pin, 1 = data is shifted (ShiftRegister)
pinMode(DATA_DUMP, INPUT);
pinMode(DEBUG1, OUTPUT);
pinMode(DEBUG2, OUTPUT);
DDRA = 0xFF; //Set port A to ouput
SPI.begin();
//SPI.mode1 Clock idel low CLOP = 0, Data sampled on falling edge CPHA = 1
SPI.beginTransaction(SPISettings(5000000, MSBFIRST, SPI_MODE1));
digitalWrite(RD, HIGH); //Stop conversion
digitalWrite(CLK_INH, HIGH); //No change on the output
digitalWrite(LD, LOW); //Load the shift register
digitalWrite(DEBUG1, LOW);
digitalWrite(DEBUG2, LOW);
attachInterrupt(digitalPinToInterrupt(20), pin_ISR, HIGH); //Call pin_ISR when pin20 goes high
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct //event structure, containts a timestamp element and an array of 18 data points
{
unsigned long int timeStamp;
unsigned char data[SENSORS];
} Event;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Event eventLog[200]; //an array of structures representing 200 events, once the 200 events have been filled the data will be printed
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void loop() {
if(fallingEdge(digitalRead(DATA_DUMP))){ //If there is falling edge on the data dump button, call the dataDump function
dataDump();
}
debug(DEBUG2);
if(eventFlag) //if the Event flag is set to true by ISR begin the conversion steps
{
debug(DEBUG1);
digitalWrite(RD,LOW); //Start conversion
while(digitalRead(INT1)){} //Wait for conversion to complete
eventLog[i].timeStamp = micros();
for (j=0; j<=SENSORS; j++) {
lockAndPop(); //lock digital value and reset conversion
PORTA = inputSelector(selector); //increment the selector pin
digitalWrite(RD, LOW); //Start new conversion
digitalWrite(CLK_INH, LOW); //Start the data transfer
eventLog[i].data[j] = SPI.transfer(0); //read a single byte from the SPI line
digitalWrite(CLK_INH, HIGH); //Inhibit clock
digitalWrite(LD, LOW);
while(digitalRead(INT1)){} //wait for previous conversion to end
}
i++;
digitalWrite(RD, HIGH);
selector = 0;
if(i>=200){
dataDump(); //if the event log hits 200 before a data dump is request, dump the data
}
eventFlag = LOW;
attachInterrupt(digitalPinToInterrupt(20), pin_ISR, HIGH);
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void pin_ISR() {
noInterrupts();
detachInterrupt(digitalPinToInterrupt(20));
eventFlag = HIGH;
interrupts();
return;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned char inputSelector (unsigned char my_selector){
if(my_selector==INPUT_MAX){ //if the current selector is at the highest value reset to 0
return 0;
}
return my_selector++; //increment the input selector by 1
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void lockAndPop (){
digitalWrite(LD, HIGH); //Lock in digital value
digitalWrite(RD, HIGH); //Reset conversion
return;
}
void dataDump (){
detachInterrupt(digitalPinToInterrupt(20));
char buf[100], *pos = buf; //create a buffer of 100 charaters, anda pointer to the begining of that buffer
char *base = buf; //create a base address to reset the buffer
unsigned int eventCount = i; //how many events occured before dump command was called
unsigned int localCount;
unsigned int localData;
Serial.begin(115200);
Serial.println(i);
for (localCount = 0; localCount<=eventCount; localCount++){
pos += sprintf(pos, "%lu", eventLog[localCount].timeStamp); //sprintf will append the data to the pointer "pos", and return the number of byte append.
for (localData = 0; localData<=SENSORS; localData++){
pos += sprintf(pos, " %d", (unsigned int)(eventLog[localCount].data[localData]));
}
Serial.println(buf);
pos = base;
}
i=0;
j=0;
Serial.end();
attachInterrupt(digitalPinToInterrupt(20), pin_ISR, HIGH);
return;
}
void debug(int pin){
digitalWrite(pin, HIGH);
digitalWrite(pin, LOW);
return;
}
bool fallingEdge (bool currentButtonState){
if(!currentButtonState&&lastButtonState){
lastButtonState = currentButtonState;
return 1;
}
lastButtonState = currentButtonState;
return 0;
}
There is a bit of noise happening on the ISR pin, but this shouldn't matter as I'm disabled that particular pin within the service routine so I wouldn't think this is an issue

Multiple If statements for Arduino

I'm new to this site and also the wonderful world of Arduino, I have been playing around with a Leonardo board and some Neopixel LEDS ( WS2812B ). I'm currently trying to set predefined colors on the LEDs with a single Pot, but also have an interrupt for a PIR sensor. I'm using the Fastled library since its great but at this point I seem to be stuck on the interrupt part. Any guidance will be appreciated !
#include "FastLED.h"
#define NUM_LEDS 3
#define DATA_PIN 6
#define PIR_PIN 2
int PIR_PIN = 0
// These constants won't change:
const int analogPin = A0; // pin that the sensor is attached to
CRGB leds[NUM_LEDS];
void setup() {
// initialize the LED pin as an output:
FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
// initialize serial communications:
pinMode(PIR_PIN, INPUT);
attachInterrupt(0, PIR_PIN, CHANGE);
}
void loop() {
// read the value of the potentiometer:
int analogValue = analogRead(analogPin);
if (analogPin < 1000)
{
leds[0] = CRGB::Red;
FastLED.show();// do Thing A
}
else if (analogPin < 500)
{
leds[0] = CRGB::Orange;
FastLED.show();// do Thing B
}
else if (analogPin < 250)
{
leds[0] = CRGB::Green;
FastLED.show();//do fuckity
}
else
{
leds[0] = CRGB::Purple;
FastLED.show();// do Thing C
}
}
void PIN_PIR () {
buttonState = digitalRead(PIR_PIN);
digitalWrite(DATA_PIN, buttonState);
}

How to control an Mcp41010 wiper position with an analog value

I am using an Mcp41010 digipot chip and am wondering how to vary the wiper position of the chip with an analog input voltage that I can adjust, I need a way of decrementing(--) the wiper position if the voltage goes over a certain point and incrementing(++) the wiper position of the chip back to the normal position this is some code that i found that just fades the wiper position up and down I need a way of controlling it. I am still very new to arduino so sorry if my explanation was clear enough.
int CS_signal = 12; // Chip Select signal onsul pin 2 of Arduino
int CLK_signal = 52; // Clock signal on pin 4 of Arduino
int MOSI_signal = 51; // MOSI signal on pin 5 of Arduino
byte cmd_byte2 = B00010001 ; // Command byte
int initial_value = 100; // Setting up the initial value
void initialize() { // send the command byte of value 100 (initial value)
spi_out(CS_signal, cmd_byte2, initial_value);
}
void spi_out(int CS, byte cmd_byte, byte data_byte){ // we need this function to send command byte and data byte to the chip
digitalWrite (CS, LOW); // to start the transmission, the chip select must be low
spi_transfer(cmd_byte); // invio il COMMAND BYTE
delay(2);
spi_transfer(data_byte); // invio il DATA BYTE
delay(2);
digitalWrite(CS, HIGH); // to stop the transmission, the chip select must be high
}
void spi_transfer(byte working) {
for(int i = 1; i <= 8; i++) { // Set up a loop of 8 iterations (8 bits in a byte)
if (working > 127) {
digitalWrite (MOSI_signal,HIGH) ; // If the MSB is a 1 then set MOSI high
} else {
digitalWrite (MOSI_signal, LOW) ; } // If the MSB is a 0 then set MOSI low
digitalWrite (CLK_signal,HIGH) ; // Pulse the CLK_signal high
working = working << 1 ; // Bit-shift the working byte
digitalWrite(CLK_signal,LOW) ; // Pulse the CLK_signal low
}
}
void setup() {
pinMode (CS_signal, OUTPUT);
pinMode (CLK_signal, OUTPUT);
pinMode (MOSI_signal, OUTPUT);
initialize();
Serial.begin(9600); // setting the serial speed
Serial.println("ready!");
}
void loop() {
for (int i = 0; i < 255; i++) {
spi_out(CS_signal, cmd_byte2, i);
Serial.println(i); delay(10);
}
for (int i = 255; i > 0; --i) {
spi_out(CS_signal, cmd_byte2, i);
Serial.println(i);
delay(10);
}
}
int CS_signal = 12; // Chip Select signal onsul pin 2 of Arduino
int CLK_signal = 52; // Clock signal on pin 4 of Arduino
int MOSI_signal = 51; // MOSI signal on pin 5 of Arduino
byte cmd_byte2 = B00010001 ; // Command byte
int initial_value = 100; // Setting up the initial value
void initialize() { // send the command byte of value 100 (initial value)
spi_out(CS_signal, cmd_byte2, initial_value);
}
void spi_out(int CS, byte cmd_byte, byte data_byte){ // we need this function to send command byte and data byte to the chip
digitalWrite (CS, LOW); // to start the transmission, the chip select must be low
spi_transfer(cmd_byte); // invio il COMMAND BYTE
delay(2);
spi_transfer(data_byte); // invio il DATA BYTE
delay(2);
digitalWrite(CS, HIGH); // to stop the transmission, the chip select must be high
}
void spi_transfer(byte working) {
for(int i = 1; i <= 8; i++) { // Set up a loop of 8 iterations (8 bits in a byte)
if (working > 127) {
digitalWrite (MOSI_signal,HIGH) ; // If the MSB is a 1 then set MOSI high
} else {
digitalWrite (MOSI_signal, LOW) ; } // If the MSB is a 0 then set MOSI low
digitalWrite (CLK_signal,HIGH) ; // Pulse the CLK_signal high
working = working << 1 ; // Bit-shift the working byte
digitalWrite(CLK_signal,LOW) ; // Pulse the CLK_signal low
}
}
void setup() {
pinMode (CS_signal, OUTPUT);
pinMode (CLK_signal, OUTPUT);
pinMode (MOSI_signal, OUTPUT);
initialize();
Serial.begin(9600); // setting the serial speed
Serial.println("ready!");
}
void loop() {
// read the input on analog pin 0:
int sensorValue = analogRead(A0);
if(sensorValue <= 200){
// 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:
Serial.println(voltage);
int i = sensorValue;{
spi_out(CS_signal, cmd_byte2, i);
Serial.println(i);
}
}
}

Resources