I am making a POV(Persistence of Vision) for my cycle. Code is taken from persistenceofvision.com which site does not exist now but is available in web archive.
the code is for single strip of addressable RGB leds. I modified it to use 3 strips .i.e 1 strip 0 degrees, 2nd at 120 degrees and third at 240 degrees, to provide the image at even lower speeds.
Problem: I am finding the value of a variable at .degrees close to 120 and 240 and saving it to global variables, x120 and x240 which are not supposed to change but the x240 changes. i dont know why?
Query : I am using variable k, k120, k240. Is it possible to substitute this as
i=120;
k[i]= whatever calculations;
My Main code
const uint8_t chipled[] PROGMEM = {0};
const uint8_t numstrip[] PROGMEM = {1}; // Number of LED strips
const uint8_t numradios[] PROGMEM = {1}; // Number of Spokes(radius)
const uint8_t radio1directo[] PROGMEM = {1};
const uint8_t radio2directo[] PROGMEM = {1};
const uint8_t radio2180[] PROGMEM = {0};
const uint8_t offset1[] PROGMEM = {0};
const uint8_t offset2[] PROGMEM = {0};
const uint8_t brillo[] PROGMEM = {128};
const uint8_t animate[] PROGMEM = {0};
//const uint8_t num_leds[] PROGMEM = {30};
const uint16_t numpasos[] PROGMEM = {152}; // number of steps
const uint16_t angreducido[] PROGMEM = {152}; // angle reduced
const uint16_t sizePolarRedu[] PROGMEM = {684};
const uint8_t PolarRedu[684] PROGMEM = {0,1,0,0,2,7,0,3,7,0,4,7,0,5,7,0,6,7,0,7,7,0,8,7,0,9,0,0,10,0,0,11,0,0,12,0,0,13,0,0,14,0,0,15,0,0,16,0,0,17,0,0,18,0,0,19,0,0,20,0,0,21,0,0,22,0,0,23,0,0,24,0,0,25,0,0,26,0,0,27,0,0,28,0,0,29,0,0,30,0,2,8,0,4,2,0,5,3,0,5,7,0,6,6,0,7,4,0,7,5,0,23,5,7,24,6,7,27,4,7,27,7,7,33,8,7,33,26,7,34,25,7,34,27,7,34,28,7,35,3,7,35,24,7,36,23,7,36,29,7,37,22,7,38,21,7,40,20,7,41,19,7,43,9,7,43,18,7,45,17,7,45,29,0,47,16,7,47,28,0,48,27,0,50,15,7,50,26,0,52,25,0,53,14,7,54,24,0,56,23,0,57,13,7,59,22,0,62,1,7,62,12,7,62,21,0,66,20,0,69,11,7,71,19,0,72,9,0,77,18,0,79,3,0,80,10,7,87,17,0,108,17,7,115,2,7,116,10,0,118,18,7,122,9,7,125,19,7,126,4,0,128,11,0,130,20,7,132,10,7,135,12,0,135,21,7,139,22,7,140,11,7,141,3,7,144,23,7,145,5,0,147,24,7,150,13,0,152,25,7,153,13,7,158,4,7,158,26,7,162,11,0,164,6,0,166,27,7,167,12,7,170,10,0,175,5,7,175,9,0,175,11,7,176,8,0,176,28,7,177,7,0,181,10,7,184,16,0,185,9,7,185,15,0,187,6,7,187,8,7,188,14,0,188,16,7,189,8,0,192,15,7,194,13,0,197,7,7,197,14,7,198,9,0,202,28,0,205,8,7,206,10,0,209,27,0,211,12,0,212,9,7,212,11,0,214,26,0,217,13,7,218,10,7,219,12,7,219,25,0,222,11,7,225,24,0,230,23,0,237,22,0,241,21,0,243,20,0,244,19,0,246,18,0,248,17,0,250,16,0,253,15,0,253,17,7,1,14,0,1,16,7,1,17,0,4,13,0,4,15,7,7,12,0,8,14,7,9,11,0,10,8,0,10,9,0,10,10,0,11,5,0,11,6,0,11,7,0,12,13,7,14,4,0,15,4,7,15,12,7,16,4,0,17,11,7,18,3,0,18,10,7,19,9,7,19,16,0,20,16,7,22,2,0,22,7,7,23,16,0,24,16,7,25,6,7,29,5,7,35,4,7,37,1,0,37,17,7,44,9,0,44,18,7,47,3,7,48,19,7,50,8,7,52,20,7,54,10,0,55,21,7,58,22,7,59,11,0,60,23,7,61,9,7,63,12,0,63,24,7,65,25,7,66,13,0,67,26,7,68,27,7,69,14,0,70,28,7,71,15,0,71,29,7,72,10,7,72,30,7,73,2,7,73,16,0,74,17,0,76,18,0,77,19,0,78,20,0,80,21,0,80,22,0,81,23,0,82,24,0,83,25,0,83,26,0,84,27,0,84,28,0,85,29,0,85,30,0,89,10,0,101,9,0};
#include <avr/pgmspace.h>
#include "FastLED.h"
#include <SoftwareSerial.h>
SoftwareSerial BT(7,8); //10 RX, 11 TX
#define DATA_PIN1 9 // 0 Degrees
#define DATA_PIN2 10 // 120 degrees
#define DATA_PIN3 11 // 240 degrees
#define LED_TYPE WS2812B
# define NUM_LEDS 30
CRGB leds[NUM_LEDS]; // original value 141
CRGB leds120[NUM_LEDS];
CRGB leds240[NUM_LEDS];
unsigned int numled;
int angAux = 0;
int anginicio = 360;
int kinicial = 0;
int angulo; // angle 0
int angulo120;
int angulo240;
unsigned int ang = 360;
unsigned int ang120 = 0;
unsigned int ang240 = 0;
unsigned int k = 0;
unsigned int k120 = 0;
unsigned int k240 = 0;
unsigned int x120 = 0;
unsigned int x240 = 0;
bool pasa = false; // Hall sensor detect
bool cambiaLed = false; // change LED
long tiempoDibujo = 0; // time drawing
long periodo = 0; // period
long periodoini = 0; // initial period
long previoustime = 0;
long tiempo = 0; // time
long contaseconds = 0; // consist seconds
long tvariable = 0;
int tiempoescritura = 700; // writing time
byte LedColour = 0;
byte vred = 0;
byte vgreen = 0;
byte vblue = 0;
int contaang = 0;
long tiempoanimate = 0;
void set_led(){
vred = 0;
vgreen = 0;
vblue = 0;
if(LedColour == 4 || LedColour == 6 || LedColour == 7 || LedColour == 1) {
vblue = 255;
}
if(LedColour == 3 || LedColour == 5 || LedColour == 6 || LedColour == 1) {
vgreen = 255;
}
if(LedColour == 2 || LedColour == 5 || LedColour == 7 || LedColour == 1) {
vred = 255;
}
}
void precompute(){
unsigned int x = 0 ;
unsigned int angle = 0;
unsigned int angular;
angular = pgm_read_byte(PolarRedu + x);
if (x / 3 >= pgm_read_word_near(angreducido + 0)) {
angular += 255;
}
for (angle = 0; angle < 360; angle++) {
while (angular == angle){
if(angle >= 120 && x120 == 0){
x120 = x;
}
if(angle >= 240 && x240 == 0){
x240 = x;
}
if(x120 != 0 && x240 != 0){
return;
}
x += 3;
if (x >= pgm_read_word_near(sizePolarRedu + 0)) {
angular = 999;
}
else{
angular = pgm_read_byte(PolarRedu + x); // value in the array PolarRedu at position value of k
if (x / 3 >= pgm_read_word_near(angreducido + 0)) {
angular += 255;
}
}
}
}
}
void get_value(){
k120 = x120;
k240 = x240;
}
void pasaIman() {
pasa = true;
}
void setup() {
//Para resetear
pinMode(A2, INPUT);
digitalWrite(A2, LOW);
//Serial.begin(9600);
FastLED.addLeds<LED_TYPE, DATA_PIN1, RGB>(leds, NUM_LEDS + pgm_read_byte(offset1 + 0)); // LED TYpe WS2812b
FastLED.addLeds<LED_TYPE, DATA_PIN2, RGB>(leds120, NUM_LEDS + pgm_read_byte(offset1 + 0));
FastLED.addLeds<LED_TYPE, DATA_PIN3, RGB>(leds240, NUM_LEDS + pgm_read_byte(offset1 + 0));
FastLED.setBrightness(pgm_read_byte(brillo + 0));
FastLED.setCorrection( TypicalLEDStrip );
attachInterrupt(digitalPinToInterrupt(2), pasaIman, RISING);
memset(leds, 0, NUM_LEDS * 3);
memset(leds120, 0, NUM_LEDS * 3);
memset(leds240, 0, NUM_LEDS * 3);
FastLED.show();
precompute();
}
void loop() {
if (pasa == true) {
pasa = false;
tiempo = micros();
periodoini = tiempo - previoustime;
periodo = tiempo - previoustime - tvariable ;
//periodo teorico //Theoretical Period
tiempoDibujo = periodo / 360;
if (tiempoDibujo < 0) tiempoDibujo = 0;
previoustime = tiempo;
get_value(); // get value of k120=252 & k240=432
k = 0;
//k120 = 252;
//k240 = 432
angulo = pgm_read_byte(PolarRedu + k); // value in the array PolarRedu at position value of k
angulo120 = pgm_read_byte(PolarRedu + k120);
angulo240 = pgm_read_byte(PolarRedu + k240);
if (k / 3 >= pgm_read_word_near(angreducido + 0)) {
angulo += 255;
}
contaang=0;
for (ang = 0; ang < 360; ang++) {
contaang++; // value 1 to 360
cambiaLed = false;
ang120 = ang + 120;
if(ang120 >= 360) ang120 -= 360;
ang240 = ang + 240;
if(ang240 >= 360) ang240 -= 360;
if(angulo == ang || angulo120 == ang120 || angulo240 == ang240) {
cambiaLed = true;
// set leds
while(angulo == ang){
if (pgm_read_byte(radio1directo + 0) == 1) {
// PolarRedu=0; k= 0,3,6,9,12...+3..675,678,681(3 less than PolarRedu[684])
numled = pgm_read_byte(PolarRedu + k + 1) - 1 + pgm_read_byte(offset1 + 0);
}
else {
//inverso es cero // inverse is zero
numled = NUM_LEDS - pgm_read_byte(PolarRedu + k+1) + pgm_read_byte(offset1 + 0);
}
LedColour = pgm_read_byte(PolarRedu + k + 2);
set_led();
leds[numled].r = vred;
leds[numled].g = vgreen;
leds[numled].b = vblue;
k += 3;
if (k >= pgm_read_word_near(sizePolarRedu + 0)) {
angulo = 999;
}
else{
angulo = pgm_read_byte(PolarRedu + k); // value in the array PolarRedu at position value of k
if (k / 3 >= pgm_read_word_near(angreducido + 0)) {
angulo += 255;
}
}
}
// Set leds120
while(angulo120 == ang120){
if (pgm_read_byte(radio1directo + 0) == 1) {
numled = pgm_read_byte(PolarRedu + k120 + 1) - 1 + pgm_read_byte(offset1 + 0);
}
else {
//inverso es cero // inverse is zero
numled = NUM_LEDS - pgm_read_byte(PolarRedu + k120 + 1) + pgm_read_byte(offset1 + 0); // No readings
}
LedColour = pgm_read_byte(PolarRedu + k120 + 2);
set_led();
leds120[numled].r = vred;
leds120[numled].g = vgreen;
leds120[numled].b = vblue;
k120 += 3;
if(k120 > pgm_read_word_near(sizePolarRedu + 0)){
k120 -= (pgm_read_word_near(sizePolarRedu + 0) + 3);
}
if (k120 == pgm_read_word_near(sizePolarRedu + 0)) {
}
//else if(k120 == x120){
else if(k120 == 252){
angulo120 = 999;
}
else{
angulo120 = pgm_read_byte(PolarRedu + k120); // value in the array PolarRedu at position value of k120
if (k120 / 3 >= pgm_read_word_near(angreducido + 0)) {
angulo120 += 255;
}
}
}
// Set leds240
while(angulo240 == ang240){
if (pgm_read_byte(radio1directo + 0) == 1) {
numled = pgm_read_byte(PolarRedu + k240 + 1) - 1 + pgm_read_byte(offset1 + 0);
}
else {
//inverso es cero // inverse is zero
numled = NUM_LEDS - pgm_read_byte(PolarRedu + k240 + 1) + pgm_read_byte(offset1 + 0); // No readings
}
LedColour = pgm_read_byte(PolarRedu + k240 + 2);
set_led();
leds240[numled].r = vred;
leds240[numled].g = vgreen;
leds240[numled].b = vblue;
k240 += 3;
if(k240 > pgm_read_word_near(sizePolarRedu + 0)){
k240 -= (pgm_read_word_near(sizePolarRedu + 0) + 3);
}
//////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
BT.println(k240);
BT.println(x240); // Value should always be 432
BT.println("=====");
if (k240 == pgm_read_word_near(sizePolarRedu + 0)) {
// Do Nothing
}
//else if(k240 == x240){
else if(k240 == 432){
angulo240 = 999;
}
else{
angulo240 = pgm_read_byte(PolarRedu + k240); // value in the array PolarRedu at position value of k
if (k240 / 3 >= pgm_read_word_near(angreducido + 0)) {
angulo240 += 255;
}
}
}
}
if (cambiaLed == true) { // ChangeLED
FastLED.show();
if (tiempoDibujo > tiempoescritura) {
delayMicroseconds(tiempoDibujo - tiempoescritura);
}
}
else {
if (tiempoDibujo > tiempoescritura) {
delayMicroseconds(tiempoDibujo + tiempoescritura * pgm_read_word_near(numpasos + 0) / (360 - pgm_read_word_near(numpasos + 0)));
}
else {
delayMicroseconds(tiempoDibujo * 360 / (360 - pgm_read_word_near(numpasos + 0)));
}
}
if (pasa == true) {
//para que se sume a tvariable algo que se supone positivo
//To add somthing that is considered positive to the variable
tvariable += (micros() - previoustime) * 360 /contaang - periodoini;
if (tvariable > 500000 || tvariable < -500000) {
tvariable = 0;
}
return;
}
} // End for (ang = 0; ang < 360 ; ang++)
//para que se sume a tvariable algo negativo
// To add a negative value to a variable
tvariable += (micros() - previoustime) - periodoini;
if (tvariable > 500000 || tvariable < -500000) {
tvariable = 0;
}
} // endif (pasa == true)
} // end of void
Hex and Proteus files.zip (34.6 KB)