Looping in Arduino - arduino

I need to loop through different Pins in an Uno board, specifically over Pin # 3,5,6,9,10,11. (The PWM ones). I know how to loop over consecutive Pins:
for (int thisPin = 2; thisPin <= 11; thisPin++)
{
pinMode(thisPin, OUTPUT);
}
I do not know how to create a list of just the Pins I want and loop though it.

Arduino nowadays even knows the c++ foreach version of loops
int pins[] = {3,5,6,9,10,11};
void setup(){
for(int pin: pins){
pinMode(pin, OUTPUT);
}
}
Just as an addendum to #Roman 's correct answer.

Create an array of the pins you want to work with and loop through that like this:
int pin[] = {3,5,6,9,10,11};
void setup(){
int len = sizeof(pin)/sizeof(pin[0]); //gets length of array
for(int i=0;i<len; i++){
pinMode(pin[i], OUTPUT);
}
}
You can choose to use len variable to make it easier to add or remove elements from the array as you're working with the code, or just set the size manually in the for loop

Related

Why does the ledstrip stop partway and then go all the way and can I make this more efficient

So I need some help reviewing and editing the code below. Is there a way to make it more efficient instead of what I did? Also, are there better ways to do some of the methods I did? Answers are appreciated greatly (I'm fairly new to Arduino).
The code below is for a corridor ledstrip that lights up when the distance sensor on the Arduino detects anything below a certain distancenear it (yes, I thought of using a motion sensor but I only had distance sensors on hand).
const int trigPin = 9;
const int echoPin = 10;
float duration, distance;
#include <FastLED.h>
#define LED_PIN 6
#define NUM_LEDS 60
int timingnum = 0;
//#define BRIGHTNESS bright
int bright = 100;///the brightness of the leds
int lednum = 60;///the number of leds available
int timer;
CRGB leds[NUM_LEDS];
void setup() {
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
Serial.begin(9600);
FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
// FastLED.setBrightness( BRIGHTNESS );
}
void loop() {
lights();
}
void sensor() { ///THIS IS CLEAN
digitalWrite(trigPin, LOW);
delayMicroseconds(timingnum);
digitalWrite(trigPin, HIGH);
delayMicroseconds(timingnum);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = (duration*.0343)/2;
Serial.print("Distance: ");
Serial.println(distance);
}
// in the lights the reason why it wouldnt output the data for the
// represented while loops is because the while loop continued running
// without the data from the distance and thus it needs to constantly
// be updated in the while loop conditional statments
void lights() {
sensor(); //data update
while (distance <= 10) {
for (int x = 0; x <= 60; x++) {
leds[x] = CRGB(255,255,255);
FastLED.show();
sensor(); //sensor update
}
for (timer = 0; timer <=800; timer++) {
sensor();
}
sensor(); //replaces the data updates above
}
sensor(); //sensor update
while (distance >= 11) {
for (int x = 0; x <= 60; x++) {
leds[x] = CRGB(0,0,0);
FastLED.show();
}
sensor(); //data update
}
}
I would be tempted to make a little function to set the RGB colors of your LED strip: void fillup(byte r, byte g, byte b). Then you would call it in two places: fillup(0,0,0) and fillup(127,127,127) (yeah, not 100% on).
Also, I'm confused why you have so many sensor() calls in the first while loop. Seems like you only need to call it once when you need updated values for distance.
Also, the comments on the sensor calls are confusing... after reading them I have no idea what sensor is supposed to do. I tend to put a comment before functions that describes what they do, and put a stand-alone comment in the code to explain what the next "paragraph" does. And I avoid banners - they get in the way.
Do you want FastLED.show() inside the loop that updates the colors? Or just after the loop, to update the hardware after the array is changed? IDK, just asking.
I usually do not mind globals, but in this case you would be better off letting sensor return the distance. Then you could while ( sensor() <= 10 ). Or use a do.. while loop with one call to sensor at the bottom if you want to keep the global.
I'd try to get rid of the floating point, too... just calculate what your thresholds are in the raw echo values, and use those. Do we really care what the internal units of measurement are?
Sorry for the long unload... There's nothing wrong with what you have.

lights not flashing off in loop function

So for a little background I am both new to Arduino and as well as to C++. I mostly deal with Javascript, so its likely I made some assumptions while programming this.
The goal of my code is to have a number of lights all flashing in sequence.
the function should turned the light on for each pin, waiting a second or so, then turning off all the pin, and then this is called again in the loop. However, in both the arduino and the online IDE, the LED flashed on but remained on.
My (incredibly generic) question is what is going wrong with my loop?
int NumOfOutputs = 1;
void setup() {
// put your setup code here, to run once:
if(NumOfOutputs >= 1){
for(int i = 2; i < NumOfOutputs + 2; i++){
pinMode(i, OUTPUT);
}
}
}
void flashSequence1(float baseRate){
for(int i = 2; i < NumOfOutputs + 2; i++){
digitalWrite(i,HIGH);
}
size_t: print(delay);
delay(baseRate * 1.00);
for(int i = 2; i < NumOfOutputs + 2; i++){
digitalWrite(i,LOW);
}
}
void flashSequence2(float baseRate, unsigned int repeat){
}
void flashSequence3(float baseRate, unsigned int repeat){
}
void loop() {
float baseRate = 1.0;
flashSequence1(baseRate);
//flashSequence2();
//flashSequence3();
}
Your delay is so short. It's simple: In order to make the human eye detect that a led is flashing, the delay between the led is on and the led is off must be greater than 10 msec. This came from my experiment with leds on Arduino.
Also, you should put a delay after led is on and a delay after led is off too.

Arduino void loop does not loop

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++)

Arduino frequency counter Issue

I am successfully using this great Arduino frequency library: Arduino frequency counter.
But there is one issue with my LEDs. They are working if I give them the value "HIGH" or "255". But however they are not working with a lower value. I have tested the LEDs in another sketch. So they are correctly wired and are working fine, also the Arduino. It seems to be a problem with the "FreqCounter::start(100);" line. If I remove it, the lower values are working, but of course the frequency counter is not...
How can I fix this problem?
Here's the code:
#include <FreqCounter.h>
unsigned long frq;
/*** OUTPUT LED ***/
int ledGreen = 9;
int ledYellow = 10;
int ledRed = 11;
void setup() {
pinMode(ledGreen, OUTPUT);
pinMode(ledYellow, OUTPUT);
pinMode(ledRed, OUTPUT);
Serial.begin(115200);
Serial.println("Frequency Counter");
}
void loop() {
/*** WRITE ***/
analogWrite(ledGreen, 255);
analogWrite(ledYellow, 100);
analogWrite(ledRed, 10);
/*** FREQUENCY COUNTER ***/
FreqCounter::f_comp = 10; // Calibration value / calibrate with a professional frequency counter
FreqCounter::start(100); // 100 ms gate time
while (FreqCounter::f_ready == 0){
frq = FreqCounter::f_freq;
}
}
According to the documentation this library repurposes TIMER1 for counting the frequency. However PWM for pins 9 and 10 requires TIMER1 with the default setup.

ATTiny array update error

I am making a persistence of vision display using an ATTiny85, programmed with Arduino using the arduino-tiny core.
It consists of a stick with 16 LEDs on it which is spun round quickly to 'draw' a picture in the air. The display buffer is represented by an array, the next index of which is output every time the timer fires. It uses a hall sensor wired to INT0 to sense top dead centre, where it zeroes the array index.
It is an 8 bit processor and I have 16 LEDs connected to LED drivers, so I actually use two arrays for the display.
So the weird thing is that when I initialised the display with a cross pattern, it displayed a bunch of broken lines; so I zeroed it first in case memory had some random stuff in it. Now it doesn't display anything (even though I write the cross pattern to it straight after zeroing it). I have no idea what is happening, any ideas?
I had it previously outputting just the index value, and the picture it traces appears to look like counting binary, so I think the hardware is working.
Note that I'm not using digitalWrite because it disables interrupts which might throw the timing off.
Here is the code: (sorry it's quite a lot)
#define COLUMNCOUNT 180
const int datapin = 4;
const int clockpin = 0;
const int latchpin = 1;
const int rxpin = 3;
const int hallpin = 2;
volatile int columns0[COLUMNCOUNT];
volatile int columns1[COLUMNCOUNT];
volatile int counter = 0;
void setup()
{
pinMode(datapin, OUTPUT);
pinMode(clockpin, OUTPUT);
pinMode(latchpin, OUTPUT);
pinMode(rxpin, INPUT);
pinMode(hallpin, INPUT);
//make sure the arrays are all zeroed
for (int i = 0; i < COLUMNCOUNT; i++)
{
columns0[i] = 0;
columns1[i] = 0;
}
//make a cross pattern
columns0[0] = 255;
columns1[0] = 255;
columns0[45] = 255;
columns1[45] = 255;
columns0[90] = 255;
columns1[90] = 255;
columns0[135] = 255;
columns1[135] = 255;
//turn on the timer (prescale CK/16)
OCR1A = 255;
OCR1C = 255;
TCNT1 = 0;
TIMSK = _BV(OCIE1A);
TCCR1 = _BV(CTC1) | _BV(CS12) | _BV(CS10);
GIMSK = _BV(INT0);
sei();
}
void loop()
{
//nothing to do here
}
ISR(TIMER1_COMPA_vect)
{
if (counter < COLUMNCOUNT)
counter++;
outputWord(columns0[counter], columns1[counter]);
}
ISR(INT0_vect)
{
counter = 0;
}
void outputByte(int b)
{
int currentBit;
for (int i = 0; i < 8; i++)
{
currentBit = (b & 128) == 128;
PORTB = _BV(clockpin) | (currentBit ? _BV(datapin) : 0);
PORTB = PORTB ^ _BV(clockpin);
b <<= 1;
}
}
void outputWord(int hi, int lo)
{
outputByte(hi);
outputByte(lo);
PORTB = _BV(latchpin);
PORTB = 0;
}
Per C standard, global variables are initialised to 0. As such,
//make sure the arrays are all zeroed
for (int i = 0; i < COLUMNCOUNT; i++)
{
columns0[i] = 0;
columns1[i] = 0;
}
is not necessary. That action is taken care of automatically when the __do_clear_bss section is executed.
Also, as per C standard, the int type must be at least 16 bits wide. In AVR, the minimum is used. If you are using the free software toolchain, it contains inttypes.h which provides the functionality offered by stdint.h and some extra stuff. This was mentioned in another answer.
The statement:
PORTB = PORTB ^ _BV(clockpin);
can be rewritten as:
PINB = _BV(clockpin);
which compiles to only 1 instruction, as per Atmel's datasheets.
Macros provided by pgmspace.h can read from flash. Notice that you can not change the contents of flash as your program runs in most AVR chips.
Beware local/global variables and stack/heap collisions when handling this much data.
I've figured it out: it's an SRAM issue. The ATTiny85 only has 512 bytes of SRAM, so it can't hold all that data in memory at the same time. I'm investigating storing the data in flash memory using the PROGMEM directive instead.
I am also doing a Persistance of Vision (POV) with the Attiny44. (I am programming it via the Arduino as an ISP)
user Ben Jackson's tip for conserving SRAM memory was spot on: I originally was using "int"'s for my arrays and my Attiny would bug out if I tried to include additional arrays- However when I simply declared all of my arrays as "unsigned char"'s my code worked fabulously as it should!
Next time I will either order attiny45's or similar for more SRAM memory, and continue to use unsigned char's for my array declarations.
Thanks for the discussion guys!

Resources