Why doesn't arduino nano together with DS3231 make LED strip work as a clock? (I use FastLED library) - arduino

For some reason, my program doesn't make the LED clock work properly. I know that the problem is either in the breadboard or the program itself, since with the other program and different circuit everything works well. Everything is fine with the power supply and the connections between the peices of the LED strip are done correctly...
The program doesn’t light up the LEDs hence making it work as a clock; even though a separate program can light up the LEDs themselves, and the other program makes the clock print into the serial monitor the time
THINGS I HAVE ALREADY DONE:
I have already tried using serial prints,
Switching up the LEDs separately using another code (everything worked fine),
Setting up the DS3231 separately and using serial prints to make sure it is working (everything worked fine),
Making sure that the code does not take too much memory,
I have additionally tried different processors to run the code (there are no mistakes in the code itself and avrdude is not displayed)
Can you, please, help me?
These are the connections on the breadboard:
Connections on the breadboard
This is the clock itself:
connection of the parts of the LED strip
You can see the code here:
#include <DS3231.h>
DS3231 rtc(SDA, SCL);
#include <FastLED.h>
#include <Wire.h>
#include <DS1307RTC.h>
#define NUM_LEDS 172 // 6*7*4 +2+2 Number of LED controlled
#define COLOR_ORDER GRB // Define color order for your strip
#define DATA_PIN 12 // Data pin for led comunication D9
CRGB leds[NUM_LEDS]; // Define LEDs strip
const byte digits[10][42] PROGMEM =
{{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, // Digit 0
{0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1}, // Digit 1
{1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1}, // Digit 2
{0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1}, // Digit 3
{0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1}, // Digit 4
{0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0}, // Digit 5
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0}, // Digit 6
{0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1}, // Digit 7
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, // Digit 8
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0}}; // Digit 9
int last_digit = 0;
int ledColor = CRGB::White; // Color used (in hex)
void setup(){
//Make the clock work and set its initial parameters
Serial.begin(9600);
rtc.begin();
//rtc.setTime(19, 48, 50); // Set the time to 12:00:00 (24hr format)
//rtc.setDate(3, 6, 2017); // Set the date to the current date
Wire.begin();
FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);
LEDS.setBrightness(200); // Set initial brightness
}
int GetTime(){
tmElements_t Now;
RTC.read(Now);
//time_t Now = RTC.Now();// Getting the current Time and storing it into a DateTime object
int hour=Now.Hour;
//Serial.println(hour); //ia going to show the hour set to the clock by the other
//Serial.println("--");
int minute=Now.Minute;
//Serial.println(minute); //ia going to show the hour set to the clock by the other
//Serial.println("--");
return (hour*100+minute);
};
// Convert time to array needed for display
void TimeToArray(){
int Now = GetTime(); // Get time
//Serial.print("Time is: ");
//Serial.println(Now);
//delay(1000);
int cursor = 271; // last led number
//dots of the clock
leds[83]=ledColor;
leds[84]=ledColor;
leds[85]=ledColor;
leds[86]=ledColor;
for(int i=1;i<=4;i++){
int digit = Now % 10; // get the last digit of the time starting from the last digit of the minutes
if (i==1){
// Serial.print("the last digit of the minures is : ");Serial.print(digit);Serial.print(" ");
cursor = 129;
for(int k=0; k<=41;k++){
// Serial.print(digits[digit][k]);
if (digits[digit][k]== 1){leds[cursor]=ledColor;}
else if (digits[digit][k]==0){leds[cursor]=0x000000;};
cursor ++;
};
// Serial.println();
}
else if (i==2){
// Serial.print("The first digit of the minutes is : ");Serial.print(digit);Serial.print(" ");
cursor =87;
for(int k=0; k<=41;k++){
// Serial.print(digits[digit][k]);
if (digits[digit][k]== 1){leds[cursor]=ledColor;}
else if (digits[digit][k]==0){leds[cursor]=0x000000;};
cursor ++;
};
// Serial.println();
}
else if (i==3){
// Serial.print("The last digit of the hours is : ");Serial.print(digit);Serial.print(" ");
cursor =41;
for(int k=0; k<=41;k++){
// Serial.print(digits[digit][k]);
if (digits[digit][k]== 1){leds[cursor]=ledColor;}
else if (digits[digit][k]==0){leds[cursor]=0x000000;};
cursor ++;
};
// Serial.println();
}
else if (i==4){
// Serial.print("The first digit of the hours is : ");Serial.print(digit);Serial.print(" ");
cursor =0;
if(digit !=0){
for(int k=0; k<=41;k++){
// Serial.print(digits[digit][k]);
if (digits[digit][k]== 1){leds[cursor]=ledColor;}
else if (digits[digit][k]==0){leds[cursor]=0x000000;};
cursor ++;
};
}
}
Now /= 10;
};
};
void loop() // Main loop
{
GetTime(); // get the time
TimeToArray(); // Get leds array with required configuration
FastLED.show(); // Display leds array
delay(1000);
}
Thank you very much in advance!!

You defined the LED digit patterns in PROGMEM, but did no call pgm_read_byte_near() to access them. As a result, you were loading digit patterns from SRAM, which is zeroed at boot time.
I had to move things around a bit to make a bit more sense of what exactly was going on.
See comment below:
#include <DS3231.h>
#include <FastLED.h>
#include <Wire.h>
#include <DS1307RTC.h>
#define NUM_LEDS 172 // 6*7*4 +2+2 Number of LED controlled
#define COLOR_ORDER GRB // Define color order for your strip
#define DATA_PIN 12 // Data pin for led comunication D9
DS3231 rtc(SDA, SCL);
CRGB leds[NUM_LEDS]; // Define LEDs strip
const byte digits[10][42] PROGMEM =
{ {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, // Digit 0
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1}, // Digit 1
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, // Digit 2
{0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, // Digit 3
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1}, // Digit 4
{0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}, // Digit 5
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}, // Digit 6
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, // Digit 7
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, // Digit 8
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}
}; // Digit 9
constexpr int ledColor = CRGB::White; // Color used (in hex)
static void ShowTime() {
//dots of the clock
leds[83] = ledColor;
leds[84] = ledColor;
leds[85] = ledColor;
leds[86] = ledColor;
tmElements_t Now;
RTC.read(Now);
for (int i = 1; i <= 4; ++i) {
int digit = 0;
int cursor = 0;
switch (i)
{
case 1:
cursor = 0;
digit = Now.Hour / 10;
break;
case 2:
cursor = 41;
digit = Now.Hour % 10;
break;
case 3:
cursor = 87;
digit = Now.Minute / 10;
break;
case 4:
cursor = 129;
digit = Now.Minute % 10;
break;
}
// added pgm_read_byte_near() to access PROGMEM data
for (int k = 0; k < 42; ++k, ++cursor)
leds[cursor] = pgm_read_byte_near(&digits[digit][k]) ? ledColor : 0;
}
FastLED.show(); // Display leds array
}
void setup() {
//Make the clock work and set its initial parameters
Serial.begin(9600);
rtc.begin();
//rtc.setTime(19, 48, 50); // Set the time to 12:00:00 (24hr format)
//rtc.setDate(3, 6, 2017); // Set the date to the current date
Wire.begin();
FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);
LEDS.setBrightness(200); // Set initial brightness
}
void loop() // Main loop
{
ShowTime();
delay(1000);
}

Related

How to get perimeter of components in an image with opencv?

I have the following matrix:
m = np.asarray(
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
[0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0],
[0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0],
[0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0],
[0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0],
[0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0],
[0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0],
[0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0],
[0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0],
[0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0],
[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
], dtype=np.uint8
)
And I apply the following few gradient transforms:
gradient = cv2.morphologyEx(m, cv2.MORPH_GRADIENT, np.ones((2,2),np.uint8))
gradient = cv2.morphologyEx(m, cv2.MORPH_GRADIENT, np.ones((3,3),np.uint8))
And I get the following results, respectively:
What I was expecting was the opposite of the image; is there a straight forward, fool-proof way to get the perimeters?
There seems to be an error in the way OpenCV applies the gradient transform.
By running the following command, I was able to obtain the correct result:
something = cv2.morphologyEx(m, cv2.MORPH_GRADIENT, np.ones((3,3),np.uint8))
gradient = something - m
gradient[gradient > 1] = 0
Use care copying my answer so that the numbers in the resultant matrix are what you need them to be.

Intersecting ranges of consecutive values in logical vectors in R

I have two logical vectors which look like this:
x = c(0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0)
y = c(0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0)
I would like to count the intersections between ranges of consecutive values. Meaning that consecutive values (of 1s) are handled as one range. So in the above example, each vector contains one range of 1s and these ranges intersect only once.
Is there any R package for range intersections which could help here?
I think this should work (calling your logical vectors x and y):
sum(rle(x & y)$values)
A few examples:
x = c(0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0)
y = c(0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0)
sum(rle(x & y)$values)
# [1] 1
x = c(1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0)
y = c(0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0)
sum(rle(x & y)$values)
# [1] 2
x = c(1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0)
y = c(0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0)
sum(rle(x & y)$values)
# [1] 3
By way of explanation, x & y gives the intersections on a per-element level, rle collapses runs of adjacent intersections, and sum counts.

R, how to overlay two geom_bars in ggplot2?

I would like to plot one bar on the top of the other one in R.
First the count of all the elements having 0, then the count of all the elements having 1, on top of it.
I tried this piece of code in R:
library(ggplot2)
var <- c(0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0)
ggplot(data.frame(var), aes(factor(var), fill=factor(var))) + geom_bar(stat="count", position="stack")
but it generated this plot:
Which is not what I want.
I would like to get something like this (I made it with KolourPaint):
Any suggestion on how to do that? Thanks!
The problem is that you've supplied a variable to the x aesthetic, factor(var), but then from what you say, you don't actually want it there. You can use some dummy variable as x in your aes: a single number or letter, or even just a blank.
Also note that count is the default stat for geom_bar, so you don't have to explicitly supply stat = "count".
library(tidyverse)
var <- c(0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0)
ggplot(data.frame(var), aes(x = "", fill = factor(var))) +
geom_bar(position = "stack")
Created on 2018-05-08 by the reprex package (v0.2.0).
A quick and dirty solution is to add an additional variable to use on your x axis.
var <- c(0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0)
var=as.data.frame(var)
var$var1=1
ggplot(data.frame(var), aes(factor(var1), fill=factor(var))) + geom_bar(stat="count", position="stack")

R - Check different matrices with a possible lag

This issue is quite tricky to explain but I am sure some of you already faced it.
So I have two matrix.
Matrix 1 (mat 1) and
Matrix 2 (mat 2)
What I want to do is to record in a third matrix (mat3) the value of mat2, after checking for matrix 1, but with a LAG. Let me explain.
After the value 1 in matrix 1, I want to check if matrix 2 as a 1 too but within the range of a certain LAG, for example, 1 or 2 episodes after (column).
For example, row number 4 has a 1 in matrix 1 at the 6th column.
So I want to check if in matrix 2 for row number 4 it has a 1 directly after or after 2 or 3 more columns.
Do you understand the idea ?
mat1 = structure(c(0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0,
0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0,
0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0,
1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1,
0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0,
0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1), .Dim = c(10L, 21L), .Dimnames = list(NULL, c("wit5.020",
"wit5.021", "wit5.022", "wit5.023", "wit5.024", "wit5.025", "wit5.026",
"wit5.027", "wit5.028", "wit5.029", "wit5.030", "wit5.031", "wit5.032",
"wit5.033", "wit5.034", "wit5.035", "wit5.036", "wit5.037", "wit5.038",
"wit5.039", "wit5.040")))
mat2 = structure(c(0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0,
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0,
0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0,
0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0,
0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0,
1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1,
0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0,
1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1,
0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0,
0, 1, 0, 1), .Dim = c(10L, 21L))
So mat3 - where I want to store the result of the check
mat3 = matrix(0, nrow = nrow(mat1), ncol = ncol(mat1))
So here is an example of a possible loop
in order to check the LAG - this loop doesn't work but it could give you an idea maybe of the solution.
I am not sure where to introduce the lag. I thought maybe in the i, but I am not sure.
for(j in 1:ncol(mat1)){
for(i in 1:nrow(mat1)){
if( mat1[i,j] == 1 & mat2[i,j] == 1 | mat2[i+1,j] == 1 | mat2[i+2,j] == 1) # lag here
{mat[i,j] <- 1}
else
{mat[i,j] <- 0}
}
}
Any ideas are very welcome.
Here's a simple way to do it:
lag <- 3 # or whatever lag you want
nr <- nrow(mat1)
nc <- ncol(mat1)
mat3 <- matrix(0, ncol=nc, nrow=nr)
for (r in 1:nr) {
for (c in 1:nc) {
if (mat1[r,c] == 1 && any(mat2[r,c:min(c+lag,nc)] == 1))
mat3[r,c] <- 1
}
}
Note the use of mat2[r,c:min(c+lag,nc)]. This selects all elements from current column c up through column c + lag, but it makes sure not to go past nc (the total number of columns). That is, this code is used to avoid an out-of-bounds error.
There's probably a faster, more vectory way of doing this, but the above code should work.

Is it possible to store Arduino data for sketch in plain text onboard Arduino?

I created this arduino sketch and it works fine, what happens is you hold a button down and a pattern of lights plays. You can see my patterns at the bottom. Each button has its own pattern to play when its held.
So this works fine, but I have a question. I'm uneasy about this because I feel that its better practice to keep my patterns outside the program. I want to know, can I store the patterns in a text file that also gets loaded onto the arduino? Is there anyway to put the patterns in a text file, and just read them all onboard the arduino?
const int buttonPin[5] = {8,9,10,11,12};
const int LEDPin[5] = {2,3,4,5,6};
int timer =0;
int millisBegin=0;
boolean reset=true;
boolean run[5] = {false,false,false,false,false};
boolean buttonOn = false;
void setup(){
Serial.begin(57600);
pinMode(buttonPin[0], INPUT);
pinMode(buttonPin[1], INPUT);
pinMode(buttonPin[2], INPUT);
pinMode(buttonPin[3], INPUT);
pinMode(buttonPin[4], INPUT);
pinMode(LEDPin[0], OUTPUT);
pinMode(LEDPin[1], OUTPUT);
pinMode(LEDPin[2], OUTPUT);
pinMode(LEDPin[3], OUTPUT);
pinMode(LEDPin[4], OUTPUT);
}
void loop()
{
for (int x=0; x<6; x++)
{
if (digitalRead(buttonPin[x]) == HIGH)
{
run[x] = true;
}
}
if (run[0] == true)
{
buttonOn = pattern1();
if (buttonOn == false)
{
run[0] = false;
}
}
if (run[1] == true)
{
buttonOn = pattern2();
if (buttonOn == false)
{
run[1] = false;
}
}
if (run[2] == true)
{
buttonOn = pattern3();
if (buttonOn == false)
{
run[2] = false;
}
}
if (run[3] == true)
{
buttonOn = pattern4();
if (buttonOn == false)
{
run[3] = false;
}
}
if (run[4] == true)
{
buttonOn = pattern5();
if (buttonOn == false)
{
run[4] = false;
}
}
}
boolean light(int button, int pattern[][6])
{
while (digitalRead(buttonPin[button])==LOW)
{
reset = true;
for (int x=0; x<5; x++){
digitalWrite(LEDPin[x],LOW);
}
buttonOn = false;
return buttonOn;
}
while (digitalRead(buttonPin[button])==HIGH)
{
if (reset == true)
{
millisBegin = millis();
reset = false;
Serial.println("reset!");
}
timer = millis() - millisBegin;
for (int x=0; x<10; x++) //Pattern amount
{
for (int y=0; y<5; y++) //Lights
{
//if else runs pattern with correct time code
if (timer>pattern[x][5]&&timer<pattern[x+1][5])
{
if (pattern[x][y]==1)
{
digitalWrite(LEDPin[y], HIGH);
}
else
{
digitalWrite(LEDPin[y], LOW);
}
}
}
}
Serial.println(timer);
if (timer > pattern[10][5]){
reset = true;
Serial.println("Over timer!");
}
}
}
boolean pattern1()
{
int pattern[11][6] = {
{0, 0, 0, 0, 0, 100}, //0
{1, 1, 0, 1, 1, 1200}, //1
{0, 0, 1, 0, 0, 2200}, //2
{1, 1, 0, 1, 1, 3200}, //3
{0, 0, 0, 0, 0, 4200}, //4
{1, 1, 1, 1, 1, 5000}, //5
{0, 0, 1, 0, 0, 6000}, //6
{1, 0, 0, 0, 0, 7000}, //7
{0, 1, 0, 1, 1, 8000}, //8arduin
{0, 0, 1, 0, 1, 9000}, //9
{0, 0, 0, 0, 0, 10000}}; //
buttonOn = light(0,pattern);
return buttonOn;
}
boolean pattern2()
{
int pattern[11][6] = {
{1, 0, 1, 0, 0, 100}, //0
{0, 1, 1, 0, 1, 180}, //1
{1, 0, 0, 0, 0, 230}, //2
{0, 1, 0, 1, 1, 340}, //3
{1, 0, 0, 1, 0, 450}, //4
{0, 0, 1, 1, 1, 500}, //5
{0, 0, 1, 0, 0, 550}, //6
{1, 0, 0, 0, 0, 600}, //7
{0, 1, 0, 1, 1, 680}, //8
{0, 0, 1, 0, 1, 800}, //9
{0, 0, 0, 0, 0, 900}}; //
buttonOn = light(1,pattern);
return buttonOn;
}
boolean pattern3()
{
int pattern[11][6] = {
{1, 1, 1, 1, 1, 100}, //0
{0, 0, 0, 0, 0, 180}, //1
{1, 1, 1, 1, 1, 230}, //2
{0, 0, 0, 0, 0, 340}, //3
{1, 1, 1, 1, 1, 450}, //4
{0, 0, 0, 0, 0, 500}, //5
{1, 1, 1, 1, 1, 550}, //6
{0, 0, 0, 0, 0, 600}, //7
{1, 1, 1, 1, 1, 680}, //8
{0, 0, 0, 0, 0, 800}, //9
{0, 0, 0, 0, 0, 810}}; //
buttonOn = light(2,pattern);
return buttonOn;
}
boolean pattern4()
{
int pattern[11][6] = {
{0, 0, 0, 0, 0, 100}, //0
{0, 0, 0, 0, 1, 500}, //1
{0, 0, 0, 1, 1, 800}, //2
{0, 0, 1, 1, 1, 900}, //3
{1, 1, 1, 1, 1, 1000}, //4
{1, 1, 1, 1, 1, 1100}, //5
{1, 1, 1, 1, 0, 1200}, //6
{1, 1, 1, 0, 0, 1300}, //7
{1, 1, 0, 0, 0, 1400}, //8
{1, 0, 0, 0, 0, 1500}, //9
{0, 0, 0, 0, 0, 1600}}; //
buttonOn = light(3,pattern);
return buttonOn;
}
boolean pattern5()
{
int pattern[11][6] = {
{0, 1, 0, 1, 0, 100}, //0
{1, 0, 1, 0, 1, 500}, //1
{0, 1, 0, 1, 0, 800}, //2
{1, 0, 1, 0, 1, 900}, //3
{0, 1, 0, 1, 0, 1000}, //4
{1, 0, 1, 0, 1, 1100}, //5
{0, 1, 0, 1, 0, 1200}, //6
{1, 0, 1, 0, 1, 1300}, //7
{0, 1, 0, 1, 0, 1400}, //8
{1, 0, 1, 0, 1, 1500}, //9
{0, 1, 0, 1, 0, 1600}}; //
buttonOn = light(4,pattern);
return buttonOn;
}
The Arduino boards do not have external storage devices where files can be stored. Of course there are shields with a SD card slot which you can add to your device. This would be overkill however.
But the Arduino has a builtin EEPROM which you can read/write using the EEPROM library.
My suggestion would be:
Extend your program to read and write to USB via Serial. You can then invent some simple text-based commands which allow you to send new patterns to the Arduino.
When the Arduino receives new patterns, it stores them in the EEPROM.
In normal operation mode the Arduino reads the patterns from EEPROM and displays them.
This way you can use your Arduino "standalone" and program it ad-hoc using any computer.

Resources