Pages: [1]   Go Down
Author Topic: char arrays and indexing -SOLVED-  (Read 1220 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hi again!

i'm trying to make a lfo with pushbutton to choose the wave form, so i make some tables, store them on flash, and output it via pwm on timer 2, all fine until here if i call the table directly but now i want to add the button (for testing i just point the index to '0'), so i put an array of char (char*) for indexing the tables and i have only garbage at pwm output
i checked the option of the array by putting a serialprint and it says the 'correct' name of the string, but for some reason the function to assign the table in memory don't works
any help will be appreciated smiley

here is the code:

Code:
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <pins_arduino.h>

//tabla seno para lfo, un ciclo
PROGMEM prog_uchar sine[] = {
  127,130,133,136,139,143,146,149,152,155,158,161,164,167,170,173,176,178,181,184,187,190,192,195,198,200,203,205,208,210,212,215,217,219,221,223,225,227,229,231,233,234,236,238,239,240,
  242,243,244,245,247,248,249,249,250,251,252,252,253,253,253,254,254,254,254,254,254,254,253,253,253,252,252,251,250,249,249,248,247,245,244,243,242,240,239,238,236,234,233,231,229,227,225,223,
  221,219,217,215,212,210,208,205,203,200,198,195,192,190,187,184,181,178,176,173,170,167,164,161,158,155,152,149,146,143,139,136,133,130,127,124,121,118,115,111,108,105,102,99,96,93,90,87,84,81,78,
  76,73,70,67,64,62,59,56,54,51,49,46,44,42,39,37,35,33,31,29,27,25,23,21,20,18,16,15,14,12,11,10,9,7,6,5,5,4,3,2,2,1,1,1,0,0,0,0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,11,12,14,15,16,18,20,21,23,25,27,29,31,
  33,35,37,39,42,44,46,49,51,54,56,59,62,64,67,70,73,76,78,81,84,87,90,93,96,99,102,105,108,111,115,118,121,124};

PROGMEM prog_uchar squa[] = {
  250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
  250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
  250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};




//funciones clear bit y set bit
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

//variables para lfo
int lfo_speed;
boolean lfo_rotate;
const int lfo_rotate_pin=2;
int lfo_wave_num=0;
char* lfo_wave[]= {"sine", "squa"};

// variables en la interrupcion 2 (lfo + velocity)
volatile byte icnt;              // var inside interrupt
volatile byte icnt1;             // var inside interrupt
volatile byte c4ms;              // counter incremented all 4ms
volatile unsigned long phaccu;   // pahse accumulator
volatile unsigned long tword_lfo;  // dds tuning word m

void setup() {


  pinMode(11,OUTPUT);      // pin11= PWM del LFO - timer 2 - OC2A
  pinMode(3, OUTPUT);   // pin3=  PWM Velocity - timer 2 - OC2B
 
  cli();


  Setup_timer2();

  sbi (TIMSK2,TOIE2);           //habilita la interrupcion del timer 2

  sei();

}

void loop () {

if (c4ms > 10) {                 // lee cada 10ms

    
    c4ms=0;
    lfo_speed=analogRead(2);      // lee el potenciometro conectado en 2 LFO_Speed
    tword_lfo=50000*lfo_speed+1000;          
  }

}

void Setup_timer2() {

  // Timer2 Clock Prescaler to : 1
  sbi (TCCR2B, CS20);
  cbi (TCCR2B, CS21);
  cbi (TCCR2B, CS22);

  // Timer2 PWM Mode set to Phase Correct PWM
  cbi (TCCR2A, COM2A0);  // clear Compare Match
  sbi (TCCR2A, COM2B1);
  sbi (TCCR2A, COM2A1);

  sbi (TCCR2A, WGM20);  // Mode 1  / Phase Correct PWM
  cbi (TCCR2A, WGM21);
  cbi (TCCR2B, WGM22);
}

ISR(TIMER2_OVF_vect) {

  phaccu=phaccu+tword_lfo; // soft DDS, phase accu with 32 bits
  icnt=phaccu >> 24;     // use upper 8 bits for phase accu as frequency information
  // read value fron ROM sine table and send to PWM

 // OCR2A=pgm_read_byte_near(sine + icnt); // pin 11 lfo
  OCR2B=pgm_read_byte_near(lfo_wave[lfo_wave_num] + icnt); // pin 3 velocity

  if (icnt1++ == 125) {  // increment variable c4ms all 4 milliseconds
    c4ms++;
    icnt1=0;
  }  
    

}
« Last Edit: February 28, 2011, 06:39:39 pm by jano » Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 212
Posts: 8975
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Your table contains character strings with the NAMES of the two tables, not a reference to the table itself.

I think you want something like:

prog_uchar* lfo_wave[]= {sine, squa};
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Left Coast, USA
Offline Offline
Sr. Member
****
Karma: 7
Posts: 499
Sometimes I just can't help myself.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

One way:
Code:
//
// Illustration of multiple function lookup tables (arrays) in Program Memory
//
//  davekw7x
//
#include <avr/pgmspace.h>

PROGMEM const prog_uchar f1[256] =
    //Put 256 values for the first function lookup table here
    { 1, 2, 3, 4, 5, 6, /*...*/};

PROGMEM const prog_uchar f2[256] =
    //Put 256 values for the second function lookup table here
    {101, 102, 103, 104, 105, 106/*...*/};

// As many as you want


//
// Table of pointers.  Entries are the addresses of the first elements of the function arrays
//
PROGMEM const prog_uchar *functionTables[] = {f1, f2};

//
//If you want names, define one for each function
//
PROGMEM const prog_char name1[] = "Potrzebie";
PROGMEM const prog_char name2[] = "Zaphod Beeblebrox";


//
// Table of pointers.  Entries are the addresses of the first chars of the name strings
//
PROGMEM const prog_char *functionNames[] = {name1, name2};


void setup()
{
    Serial.begin(9600);
    for (int functionNumber = 0; functionNumber < 2; functionNumber++) {

        char nameBuffer[80] = {0}; // Must be large enough to hold longest name (+ 1 char for terminating zero)

        // Read pointer from table of pointers
        prog_char *namePointer = (prog_char *)pgm_read_word(&functionNames[functionNumber]);
        // Could write it like this:
        //prog_char *namePointer = (prog_char *)pgm_read_word(functionNames + functionNumber);
        
        // Copy the name from the name table to the buffer for printing.
        strncpy_P(nameBuffer, (char *)namePointer, sizeof(nameBuffer)-1);
        Serial.print("Function number ");Serial.print(functionNumber);Serial.print(": Name is '");
        Serial.print(nameBuffer);Serial.println("'");
        for (int icnt = 0; icnt < 6; icnt++) {

            // Read pointer from table of pointers
            prog_uchar *functionPointer = (prog_uchar *)pgm_read_word(&functionTables[functionNumber]);
            // Could write it like this:
            //prog_uchar *functionPointer = (prog_uchar *)pgm_read_word(functionTables+functionNumber);
            
            // Read byte from the table
            byte x = pgm_read_byte(&functionPointer[icnt]);
            //Could write it like this:
            //byte x = pgm_read_byte(functionPointer+icnt);

            Serial.print("  ");Serial.print(icnt);Serial.print(": ");Serial.println(x,DEC);
        }
        Serial.println();
    }
}

void loop(){}

Output:


Function number 0: Name is 'Potrzebie'
  0: 1
  1: 2
  2: 3
  3: 4
  4: 5
  5: 6

Function number 1: Name is 'Zaphod Beeblebrox'
  0: 101
  1: 102
  2: 103
  3: 104
  4: 105
  5: 106


Regards,

Dave
« Last Edit: February 23, 2011, 07:47:41 pm by davekw7x » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

thanks for reply! i will try as soon as i can do  smiley-roll-blue
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

yes! it works!

thanks Dave for the hint. here is the working code (far to be complete, but get closing):

Code:
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <pins_arduino.h>

//tabla seno para lfo, un ciclo
PROGMEM const prog_uchar seno[] = {
  127,130,133,136,139,143,146,149,152,155,158,161,164,167,170,173,176,178,181,184,187,190,192,195,198,200,203,205,208,210,212,215,217,219,221,223,225,227,229,231,233,234,236,238,239,240,
  242,243,244,245,247,248,249,249,250,251,252,252,253,253,253,254,254,254,254,254,254,254,253,253,253,252,252,251,250,249,249,248,247,245,244,243,242,240,239,238,236,234,233,231,229,227,225,223,
  221,219,217,215,212,210,208,205,203,200,198,195,192,190,187,184,181,178,176,173,170,167,164,161,158,155,152,149,146,143,139,136,133,130,127,124,121,118,115,111,108,105,102,99,96,93,90,87,84,81,78,
  76,73,70,67,64,62,59,56,54,51,49,46,44,42,39,37,35,33,31,29,27,25,23,21,20,18,16,15,14,12,11,10,9,7,6,5,5,4,3,2,2,1,1,1,0,0,0,0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,11,12,14,15,16,18,20,21,23,25,27,29,31,
  33,35,37,39,42,44,46,49,51,54,56,59,62,64,67,70,73,76,78,81,84,87,90,93,96,99,102,105,108,111,115,118,121,124};

PROGMEM const prog_uchar squa[] = {
  250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
  250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
  250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

PROGMEM const prog_uchar *functionTables[] = {seno, squa};


//funciones clear bit y set bit
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

//variables para lfo
int lfo_speed;
boolean lfo_rotate;
const int lfo_rotate_pin=2;
int lfo_wave_num=1;


// variables en la interrupcion 2 (lfo + velocity)
volatile byte icnt;              // var inside interrupt
volatile byte icnt1;             // var inside interrupt
volatile byte c4ms;              // counter incremented all 4ms
volatile unsigned long phaccu;   // pahse accumulator
volatile unsigned long tword_lfo;  // dds tuning word m

void setup() {


  pinMode(11,OUTPUT);      // pin11= PWM del LFO - timer 2 - OC2A
  pinMode(3, OUTPUT);    // pin3=  PWM Velocity - timer 2 - OC2B
 
  cli();


  Setup_timer2();

  sbi (TIMSK2,TOIE2);           //habilita la interrupcion del timer 2

  sei();

}

void loop () {

if (c4ms > 10) {                 // lee cada 10ms

   
    c4ms=0;
    lfo_speed=analogRead(2);      // lee el potenciometro conectado en 2 LFO_Speed
    tword_lfo=50000*lfo_speed+1000;           
  }
 
 
 
   
 
}

void Setup_timer2() {

  // Timer2 Clock Prescaler to : 1
  sbi (TCCR2B, CS20);
  cbi (TCCR2B, CS21);
  cbi (TCCR2B, CS22);

  // Timer2 PWM Mode set to Phase Correct PWM
  cbi (TCCR2A, COM2A0);  // clear Compare Match
  sbi (TCCR2A, COM2B1);
  sbi (TCCR2A, COM2A1);

  sbi (TCCR2A, WGM20);  // Mode 1  / Phase Correct PWM
  cbi (TCCR2A, WGM21);
  cbi (TCCR2B, WGM22);
}

ISR(TIMER2_OVF_vect) {

  phaccu=phaccu+tword_lfo; // soft DDS, phase accu with 32 bits
  icnt=phaccu >> 24;     // use upper 8 bits for phase accu as frequency information
 
  // read value fron ROM sine table and send to PWM
  prog_uchar *functionPointer = (prog_uchar *)pgm_read_word(&functionTables[lfo_wave_num]);
  OCR2A=pgm_read_byte(&functionPointer[icnt]); // pin 11 lfo

  if (icnt1++ == 125) {  // increment variable c4ms all 4 milliseconds
    c4ms++;
    icnt1=0;
  }   
     

}
Logged

Pages: [1]   Go Up
Jump to: