Hello all,
I got my first UNO a few weeks ago and have been managing my way thru various projects here and there. One of which was to incorporate some LEDs into some toy helicopters for flying at night -- big thanks to mr. klein! Here's a video of how things turned out: S107 + 50hp mod - YouTube
I built a socket into the project to allow for adding more patterns later and this is where i'm running into some trouble: if i add too many entries to my array, the program fails to operate correctly.
Here's another vid to further illustrate the problem: counting with arrays - YouTube
The first 25 seconds show normal operation while the latter part of the video shows what happens after uncommenting the line in the brightness_pattern array. It doesn't matter which line is commented out in the array, 7 entries is okay but 8 is too many.
FWIW, I originally wrote the program with an UNO board but then trimmed it down for use on an ATTiny44 at 8MHz
The code:
//
// www.blinkenlight.net
//
// Copyright 2011 Udo Klein
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses/
#include <EEPROM.h>
uint8_t get_next_count(const uint8_t count_limit) {
// n cells to use --> 1/n wear per cll --> n times the life time
const uint16_t cells_to_use = 256;
// default cell to change
uint8_t change_this_cell = 0;
// value of the default cell
uint8_t change_value = EEPROM.read(change_this_cell);
// will be used to aggregate the count_limit
// must be able to hold values up to cells_to_use*255 + 1
uint32_t count = change_value;
for (uint16_t cell = 1; cell < cells_to_use; ++cell) {
uint8_t value = EEPROM.read(cell);
// determine current count by cummulating all cells
count += value;
if (value != change_value ) {
// at the same time find at least one cell that differs
change_this_cell = cell;
}
}
// Either a cell differs from cell 0 --> change it
// Otherwise no cell differs from cell 0 --> change cell 0
// Since a cell might initially hold a value of -1 the % operator must be applied twice
EEPROM.write(change_this_cell, (EEPROM.read(change_this_cell) % count_limit + 1) % count_limit);
// return the new count
return (count + 1) % count_limit;
}
uint8_t brightness_pattern_1(const int8_t led, const int8_t pos) {
switch (abs(led-pos+2)) {
case 0: return 40;
case 1: return 20;
case 2: return 10;
case 3: return 1;
default: return 1; //brightness
}
}
uint8_t brightness_pattern_2(const int8_t led, const int8_t pos) {
switch (abs(led-pos+2)) {
case 0: return 40;
case 1: return 20;
case 2: return 1;
case 3: return 0;
default: return 0; //brightness
}
}
uint8_t brightness_pattern_3(const int8_t led, const int8_t pos) {
switch min(abs(led-pos-1),abs(10-led-pos-1)) {
case 0: return 40;
case 1: return 20;
case 2: return 10;
case 3: return 1;
default: return 1; //brightness
}
}
uint8_t brightness_pattern_4(const int8_t led, const int8_t pos) {
switch min(abs(led-pos-1),abs(10-led-pos-1)) {
case 0: return 40;
case 1: return 20;
case 2: return 1;
case 3: return 0;
default: return 0; //brightness
}
}
uint8_t brightness_pattern_5(const int8_t led, const int8_t pos) {
int8_t tmp = 2*pos - abs(2*led-10)-2; //last number is middle delay
return (tmp>0? tmp+tmp>>1: 1); //brightness
}
uint8_t brightness_pattern_6(const int8_t led, const int8_t pos) {
int8_t tmp = 2*pos - abs(2*led-10)-2; //last number is middle delay
return (tmp>0? tmp+tmp>>1: 0); //brightness
}
uint8_t brightness_pattern_7(const int8_t led, const int8_t pos) { // inverse of brightness_pattern_8
int8_t tmp = abs(2*led-10) + 8 - pos; // abs(2*led-[#LEDs - 1]) + delay in middle - pos - delay at outside
return (tmp>0? tmp+tmp>>1: 0); //brightness
}
uint8_t brightness_pattern_8(const int8_t led, const int8_t pos) { // inverse of brightness_pattern_7
int8_t tmp = abs(2*led-10) + 25 - 2*pos; // abs(2*led-[#LEDs - 1]) + delay in middle - pos - delay at outside
return (tmp>0? tmp+tmp>>1: 0); //brightness
}
typedef uint8_t (*brightness_pattern)(const int8_t, const int8_t);
brightness_pattern pattern[] = { brightness_pattern_1,
brightness_pattern_2,
// brightness_pattern_3, *************the problem seems to be here in this array*************
brightness_pattern_4,
brightness_pattern_5,
brightness_pattern_6,
brightness_pattern_7,
brightness_pattern_8,
};
brightness_pattern brightness;
void setup() {
for (uint8_t pin=0; pin<11; ++pin) {
pinMode(pin, OUTPUT);
}
brightness = pattern[get_next_count(sizeof(pattern)/sizeof(pattern[0]))];
}
void pulse_width_modulation(const uint8_t pos) {
for(uint8_t times=0; times<8; ++times) {
for (uint8_t pass=0; pass<40; ++pass) { //brightness on or off...overall brightness (flicker)
for (int8_t led=-3; led<11; ++led) {
digitalWrite(led, (brightness(led, pos) > pass));
}
}
}
}
void loop() {
// wait 2 milliseconds before the next loop
// for the analog-to-digital converter to settle
// after the last reading:
//delay(2);
static uint8_t pos=0;
while(pos<16) {
pulse_width_modulation(pos);
++pos;
}
while(pos>0) {
--pos;
pulse_width_modulation(pos);
}
}
thanks!