Arduino void loop does not loop - arduino

I am trying to blink an Array of LEDs hooked up to a pin on the Arduino.
When I upload the code onto my Arduino :
//array of pins
int allLEDPins[4] = {2, 3, 4, 5};
//the chase function
void Chaster(int* anArray) {
for (int i = 0; i < 5; i++) {
digitalWrite(allPins[i], HIGH);
delay(200);
digitalWrite(allPins[i], LOW);
delay(200);
}
}
//setup pins
void setup() {
pinMode(allPins[0], OUTPUT);
pinMode(allPins[1], OUTPUT);
pinMode(allPins[2], OUTPUT);
pinMode(allPins[3], OUTPUT);
}
void loop() {
Chaster(allLEDPins);
}
The loop function does not loop. I am using an Arduino Zero in Arduino IDE 1.6.8 on my Windows 10 machine. Thank you in advance.

You are accessing an index out of range in the for loop inside the function Chaster. Note that your array allLEDPins have only 4 elements and you tried to access allLEDPins[4] while the last element is allLEDPins[3]. This causes an error during running time.
In order to fix that, replace for (int i = 0; i < 5; i++) by for (int i = 0; i < 4; i++)

Related

Using a Arduino Mega instead of a Uno for a capacitive sensor

I was trying to use a Arduino Mega to substitute a Arduino Uno. The folliwing code works fine in Uno but doesn't work on Mega (I already changed the ports to it). It is used for a Capacitive touchsensor:
#define resolution 8
#define mains 60 // 60: north america, japan; 50: most other places
#define refresh 2 * 1000000 / mains
void setup() {
Serial.begin(9600);
// unused pins are fairly insignificant,
// but pulled low to reduce unknown variables
for(int i = 2; i < 14; i++) {
pinMode(i, OUTPUT);
digitalWrite(i, LOW);
}
for(int i =22; i < 53; i++){
pinMode(i, OUTPUT);
digitalWrite(i, LOW);
}
pinMode(8, INPUT);
startTimer();
}
void loop() {
Serial.println(time(8, B00100000), DEC);
}
long time(int pin, byte mask) {
unsigned long count = 0, total = 0;
while(checkTimer() < refresh) {
// pinMode is about 6 times slower than assigning
// DDRB directly, but that pause is important
pinMode(pin, OUTPUT);
PORTH = 0;
pinMode(pin, INPUT);
while((PINH & mask) == 0)
count++;
total++;
}
startTimer();
return (count << resolution) / total;
}
extern volatile unsigned long timer0_overflow_count;
void startTimer() {
timer0_overflow_count = 0;
TCNT0 = 0;
}
unsigned long checkTimer() {
return ((timer0_overflow_count << 8) + TCNT0) << 2;
}
I would like to know what I need to change on the Timer interrupt stuff to make it work properly.

Arduino for loop completely not functional

I am trying to send data from an accelerometer to Java from an Arduino. I am using delta time to limit it to sending only every 250 ms.
The problem is that all the Java program is reading is the first message sent in the setup() over and over.
I added a test Serial.write to check if the program is ever entering the delta time block, and it seems to be sending (or at least, reading) the first 2 characters of that message. The Arduino code is below.
#include <SparkFun_MMA8452Q.h>
int sleepPin = 7;
int stepPin = 6;
int buttonPin = 8;
int stepCount = 0;
boolean stepMode = true;
int delTime = 5000;
MMA8452Q accel; //accelerometer
void setup() {
Serial.begin(9600);
while (millis() < 4000); //wait so I can start java program
Serial.write("Connected");
//set pins
pinMode(sleepPin, OUTPUT);
pinMode(stepPin, OUTPUT);
pinMode(buttonPin, INPUT);
digitalWrite(stepPin, HIGH); //starts in step mode
delTime = millis() + 250;
}
void loop() {
if (digitalRead(buttonPin) == HIGH) stepMode = !stepMode;
if (millis() > delTime) {
Serial.write("delTime"); //test case
//set led's according to mode
if (stepMode) {
digitalWrite(stepPin, HIGH);
digitalWrite(sleepPin, LOW);
} else {
digitalWrite(stepPin, HIGH);
digitalWrite(sleepPin, LOW);
}
//create string to store data
String data = "";
if (stepMode) data += "s"; //s is step mode key
else data += "z"; //z is sleep mode key
//add actual reading stuff
data += String(accel.getX()) + "," + String(accel.getY());
Serial.write(data.c_str()); //send the lad over
}
}
The Java side is nearly identical (sans the conditions of an if statement, but it doesn't matter because if it doesn't meet the statement it just prints what it sees) to a functional program for serial communication that I've used before. I can include it if necessary though.
The Java console output appears as:
Connected
de
Connected
de
Connected
de
where a new iteration appears about once a second. What am I doing that prevents the Arduino from sending the data?
Not a proper answer yet, more of a test, but I couldn't fit it in a comment.
Changes made:
delTime is now an unsigned long int;
delTime is now reset at the end of the loop();
String object and manipulations were replaced by heap-friendlier code.
Added accel.begin();
Let me know if this works for you, and if not, where it complains. Haven't fully tested the code. You could also try replacing accel.getX() and accel.getY() with numbers; they return short ints, I think.
BTW the button needs debouncing.
#include <SparkFun_MMA8452Q.h>
int sleepPin = 7;
int stepPin = 6;
int buttonPin = 8;
boolean stepMode = true;
unsigned long int delTime = 0;
MMA8452Q accel; //accelerometer
void setup(){
Serial.begin(9600);
while(millis() < 4000); //wait so I can start java program
Serial.write("Connected");
//set pins
pinMode(sleepPin, OUTPUT);
pinMode(stepPin, OUTPUT);
pinMode(buttonPin, INPUT);
accel.begin();
digitalWrite(stepPin, HIGH); //starts in step mode
delTime = millis() + 250;
}
void loop() {
char str[15];
if (digitalRead(buttonPin) == HIGH)
stepMode = !stepMode;
if (millis() > delTime) {
//set led's according to mode
if (stepMode) {
digitalWrite(stepPin, HIGH);
digitalWrite(sleepPin, LOW);
Serial.write('s');
} else {
digitalWrite(stepPin, HIGH);
digitalWrite(sleepPin, LOW);
Serial.write('z');
}
sprintf(str, "%d", accel.getX());
Serial.write(str);
Serial.write(',');
sprintf(str, "%d", accel.getY());
Serial.write(str);
Serial.write('\n');
delTime = millis() + 250;
}
}

Arduino: Pin time inactivity/activity

The purpose of the following Arduino code is to interface with the high and low signals sent from a Raspberry Pi; the full explanation is rather complex so I'll spare you the waste in time. The signals sent from the Pi (pins 10 and 11) turn a stepper motor connected to an A4988 driver clockwise or counterclockwise. The pins that dictate this out of the Arduino are the step and direction pins (9 and 8). What I am trying to accomplish is to enable the sleepPin after 60 seconds of pin 10 and 11 inactivity.
Likewise, in the same fashion, I want to stop accepting input from pin 10 and 11 if they both read the same input signal for more than 3 seconds. I've looked up methods on how to incorporate time into Arduino script but do not know how to incorporate it in this instance.
byte directionPin = 9;
byte stepPin = 8;
byte sleepPin = 12;
byte buttonCWpin = 10;
byte buttonCCWpin = 11;
boolean buttonCWpressed = false;
boolean buttonCCWpressed = false;
long previousMillis = 0;
long interval = 1000;
void setup() {
//determines length of stepper movement
pinMode(directionPin, OUTPUT);
pinMode(stepPin, OUTPUT);
//moves motors clockwise or counterclockwise
pinMode(buttonCWpin, INPUT_PULLUP);
pinMode(buttonCCWpin, INPUT_PULLUP);
}
void loop() {
readButtons();
actOnButtons();
}
void readButtons() {
buttonCCWpressed = false;
buttonCWpressed = false;
if (digitalRead(buttonCWpin) == LOW) {
buttonCWpressed = true;
}
if (digitalRead(buttonCCWpin) == LOW) {
buttonCCWpressed = true;
}
}
void actOnButtons() {
if (buttonCWpressed == true) {
digitalWrite(directionPin, LOW);
for(int x = 0; x < 1; x++) {
digitalWrite(stepPin,HIGH);
delayMicroseconds(515);
digitalWrite(stepPin,LOW);
delayMicroseconds(515);
}
}
if (buttonCCWpressed == true) {
digitalWrite(directionPin, HIGH);
for(int x = 0; x < 1; x++) {
digitalWrite(stepPin,HIGH);
delayMicroseconds(515);
digitalWrite(stepPin,LOW);
delayMicroseconds(515);
}
}
}
Any help would be greatly appreciated along with any tips or concerns.
Thank You.
If you have the luxury to use pins 2 and 3 rather than pins 10 and 11 (assuming you have an Arduino Uno for instance), it could be useful to work with external interrupts.
As a solution for your first problem, here's a minimal code that should put the sleep pin high after 60 seconds of inactivity on both direction pins 2 & 3:
volatile long int last_activity;
void setup(){
attachInterrupt(2, tstamp, CHANGE);
attachInterrupt(3, tstamp, CHANGE);
pinMode(2, INPUT); // your new CW pin
pinMode(3, INPUT); // your new CCW pin
pinMode(12, OUTPUT);
digitalWrite(12, LOW);
last_activity = millis();
}
void loop(){
if (millis() - last_activity > 60e3) {
digitalWrite(12, HIGH);
// do some other things...
}
}
void tstamp(){
last_activity = millis();
}
Now for your second problem, what exactly do you mean by "stop accepting input from pins 10 and 11"? If you only need to check that their state is the same, adding volatile long int last_common_state; in the preamble and checking for digitalRead(2) == digitalRead(3); in tstamp()'s body to update last_common_state should get you on the right track.

analogWrite for LED_BUILTIN does not work

I'm trying to make the LED on the Wemos D1 mini R2 ESP8266 light up gradually.
I try this code:
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
for (int i = 0; i < 200; i++){
analogWrite(LED_BUILTIN, i);
delay(10);
}
for (int i = 200; i > 0; i--){
analogWrite(LED_BUILTIN, i);
delay(10);
}
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
delay (2000);
}
And it does not work. I changed LED_BUILTIN to D3 and it works, but when I changed LED_BUILTIN to D4, it doesn't work.
analogWrite command is for sending pwm signal in different duty-cycle
as far as I know the built_in led is not capable of working in pwm mode just regular on-off
It looks like the LED is wired to D3.

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

Resources