I want to convert Arduino code to ESP32 code

This is my first dot matrix work using ESP32, and I am not sure of the difference between Arduino code and ESP32 code. I would like to know how to write the ESP32 code using the Arduino code here as an example and the difference between the two.

#include <avr/pgmspace.h>
#include <avr/interrupt.h> 
#include <avr/io.h>

int A = 2;
int B = 3;
int C = 4;
int D = 5;
int Data_Red = 6;
int Data_Green = 7;
int Clk = 8;
int LE = 9;
int OE = 10;

const int __attribute__((progmem)) string[][16]={
0x00,0x00,0x380,0x380,0x6c0,0x6c0,0x6c0,0xc60,0xc60,0xfe0,0x1830,0x1830,0x1830,0x00,0x00,0x00, //A
0x00,0x00,0x7f0,0xc30,0xc30,0xc30,0x630,0x7f0,0xc30,0x1830,0x1830,0xc30,0x7f0,0x00,0x00,0x00, //B
0x00,0x00,0x7c0,0xc60,0x1830,0x30,0x30,0x30,0x30,0x30,0x1830,0xc60,0x7c0,0x00,0x00,0x00, //C
0x00,0x00,0x3f0,0x630,0xc30,0x1830,0x1830,0x1830,0x1830,0x1830,0xc30,0x630,0x3f0,0x00,0x00,0x00, //D
0x00,0x00,0xff0,0x30,0x30,0x30,0x30,0x7f0,0x30,0x30,0x30,0x30,0xff0,0x00,0x00,0x00, //E
0x00,0x00,0xff0,0x30,0x30,0x30,0x30,0x7f0,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x00, //F
0x00,0x00,0xf80,0x18c0,0x3060,0x30,0x30,0x3e30,0x3030,0x3030,0x3060,0x38c0,0x3f80,0x00,0x00,0x00, //G
0x00,0x00,0x1830,0x1830,0x1830,0x1830,0x1830,0x1ff0,0x1830,0x1830,0x1830,0x1830,0x1830,0x00,0x00,0x00, //H
0x00,0x00,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x00, //I
0x00,0x00,0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x198,0x198,0xf0,0x00,0x00,0x00, //J
0x00,0x00,0xc30,0x630,0x330,0x1b0,0xf0,0x1f0,0x330,0x330,0x630,0xc30,0xc30,0x00,0x00,0x00, //K
0x00,0x00,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0xff0,0x00,0x00,0x00, //L
0x00,0x00,0x3018,0x3018,0x3838,0x3838,0x3c78,0x3c78,0x36d8,0x36d8,0x3398,0x3398,0x3018,0x00,0x00,0x00, //M
0x00,0x00,0xc30,0xc70,0xc70,0xcf0,0xcf0,0xdb0,0xdb0,0xf30,0xf30,0xe30,0xe30,0x00,0x00,0x00, //N
0x00,0x00,0x7c0,0xc60,0x1830,0x3018,0x3018,0x3018,0x3018,0x3018,0x1830,0xc60,0x7c0,0x00,0x00,0x00, //O
0x00,0x00,0x7f0,0xc30,0x1830,0x1830,0xc30,0x7f0,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x00, //P
0x00,0x00,0x7c0,0xc60,0x1830,0x3018,0x3018,0x3018,0x3018,0x3318,0x1e30,0xc60,0x1fc0,0x00,0x00,0x00, //Q
0x00,0x00,0x7f0,0xc30,0x1830,0x1830,0xc30,0x7f0,0xc30,0x1830,0x1830,0x1830,0x1830,0x00,0x00,0x00, //R
0x00,0x00,0x7c0,0xc60,0x1830,0x30,0xe0,0x780,0xc00,0x1800,0x1830,0xc60,0x7c0,0x00,0x00,0x00, //S
0x00,0x00,0xff0,0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x00,0x00,0x00, //T
0x00,0x00,0x1830,0x1830,0x1830,0x1830,0x1830,0x1830,0x1830,0x1830,0x1830,0xc60,0x7c0,0x00,0x00,0x00, //U
0x00,0x00,0xc30,0xc30,0xc30,0x660,0x660,0x660,0x3c0,0x3c0,0x3c0,0x180,0x180,0x00,0x00,0x00, //V
0x00,0x00,0x6186,0x6186,0x6186,0x33cc,0x33cc,0x33cc,0x1e78,0x1e78,0x1e78,0xc30,0xc30,0x00,0x00,0x00, //W
0x00,0x00,0xc30,0xc30,0x660,0x660,0x3c0,0x180,0x3c0,0x660,0x660,0xc30,0xc30,0x00,0x00,0x00, //X
0x00,0x00,0xc30,0xc30,0x660,0x660,0x3c0,0x180,0x180,0x180,0x180,0x180,0x180,0x00,0x00,0x00, //Y
0x00,0x00,0xff0,0xc00,0x600,0x300,0x300,0x180,0xc0,0xc0,0x60,0x30,0xff0,0x00,0x00,0x00, //Z
0x00,0x00,0x380,0x380,0x6c0,0x6c0,0x6c0,0xc60,0xc60,0xfe0,0x1830,0x1830,0x1830,0x00,0x00,0x00, //A
0x00,0x00,0x7f0,0xc30,0xc30,0xc30,0x630,0x7f0,0xc30,0x1830,0x1830,0xc30,0x7f0,0x00,0x00,0x00, //B
};

unsigned char Dot_char_cnt=0; 
unsigned char flag_cnt=0; 
unsigned char move_motion=0;
unsigned int Move_cnt=16;
unsigned int Move_cnt2=0;
unsigned int up_cnt=0;
unsigned int up_cnt2=16;
unsigned int str_speed_cnt=0;
bool flag_Oe=0;

ISR(TIMER2_OVF_vect){  
  static bool output = HIGH; 
  digitalWrite(1, output);
  output = !output;
  
  static unsigned int string_moving_speed_value=500;
  static unsigned int cnt=0;
  
  if(flag_Oe)
  {
    digitalWrite(OE, LOW);
    cnt++;
    if(cnt>=5)
    {
      flag_Oe=0;
      cnt=0;
      digitalWrite(OE, HIGH);
    }
  }
  str_speed_cnt++;
  if(str_speed_cnt>string_moving_speed_value) 
  {
    str_speed_cnt=0;
    up_cnt2--;
    up_cnt++;
    if(up_cnt2==0||up_cnt==16){
      up_cnt2=16;
      up_cnt=0;
    
      move_motion++;
      if(move_motion>1){
        move_motion=0;
        Dot_char_cnt+=2;      
        flag_cnt++;
        if(flag_cnt==3)
        {
          flag_cnt=0; 
        }
      }
    }
  }
  TCNT2=0xe7;
}

void setup() {
  pinMode(A, OUTPUT);
  pinMode(B, OUTPUT);
  pinMode(C, OUTPUT);
  pinMode(D, OUTPUT);
  pinMode(Data_Red, OUTPUT);
  pinMode(Data_Green, OUTPUT);
  pinMode(Clk, OUTPUT);
  pinMode(LE, OUTPUT);
  pinMode(OE, OUTPUT);
  pinMode(1, OUTPUT);
  
  TCCR2A=0x00;
  TCCR2B=0x04;
  TIMSK2=0x01;
  TCNT2=0xe7;
  
  SREG=0x80;
}

void row_dynamic()
{
    static unsigned int str_cnt=0;   
    
    switch(str_cnt)//ROW SHIFT!
    {
    case 0:digitalWrite(A, LOW); digitalWrite(B, LOW); digitalWrite(C, LOW); digitalWrite(D, LOW); break;         //1행 LED
    case 1:digitalWrite(A, HIGH); digitalWrite(B, LOW); digitalWrite(C, LOW); digitalWrite(D, LOW); break;        //2행 LED
    case 2:digitalWrite(A, LOW); digitalWrite(B, HIGH); digitalWrite(C, LOW); digitalWrite(D, LOW); break;        //3행 LED
    case 3:digitalWrite(A, HIGH); digitalWrite(B, HIGH); digitalWrite(C, LOW); digitalWrite(D, LOW); break;       //4행 LED
    case 4:digitalWrite(A, LOW); digitalWrite(B, LOW); digitalWrite(C, HIGH); digitalWrite(D, LOW); break;        //5행 LED
    case 5:digitalWrite(A, HIGH); digitalWrite(B, LOW); digitalWrite(C, HIGH); digitalWrite(D, LOW); break;       //6행 LED
    case 6:digitalWrite(A, LOW); digitalWrite(B, HIGH); digitalWrite(C, HIGH); digitalWrite(D, LOW); break;       //7행 LED
    case 7:digitalWrite(A, HIGH); digitalWrite(B, HIGH); digitalWrite(C, HIGH); digitalWrite(D, LOW); break;      //8행 LED
    case 8:digitalWrite(A, LOW); digitalWrite(B, LOW); digitalWrite(C, LOW); digitalWrite(D, HIGH); break;        //9행 LED
    case 9:digitalWrite(A, HIGH); digitalWrite(B, LOW); digitalWrite(C, LOW); digitalWrite(D, HIGH); break;       //10행 LED
    case 10:digitalWrite(A, LOW); digitalWrite(B, HIGH); digitalWrite(C, LOW); digitalWrite(D, HIGH); break;      //11행 LED
    case 11:digitalWrite(A, HIGH); digitalWrite(B, HIGH); digitalWrite(C, LOW); digitalWrite(D, HIGH); break;     //12행 LED
    case 12:digitalWrite(A, LOW); digitalWrite(B, LOW); digitalWrite(C, HIGH); digitalWrite(D, HIGH); break;      //13행 LED
    case 13:digitalWrite(A, HIGH); digitalWrite(B, LOW); digitalWrite(C, HIGH); digitalWrite(D, HIGH); break;     //14행 LED
    case 14:digitalWrite(A, LOW); digitalWrite(B, HIGH); digitalWrite(C, HIGH); digitalWrite(D, HIGH); break;     //15행 LED
    case 15:digitalWrite(A, HIGH); digitalWrite(B, HIGH); digitalWrite(C, HIGH); digitalWrite(D, HIGH); break;    //16행 LED
    } 
    str_cnt++; 
    if(str_cnt==16)
    {
    str_cnt=0;   
    }         
}

void shift_Register(unsigned char out)
{
  unsigned char clk=0;          
  
  for(clk=0;clk<8;clk++){         
    if(out&(0x80>>clk))
      {
        switch(flag_cnt){
         case 0:digitalWrite(Data_Green, LOW);digitalWrite(Data_Red, HIGH);break;    //Red
         case 1:digitalWrite(Data_Green, HIGH);digitalWrite(Data_Red, LOW);break;    //Green
         case 2:digitalWrite(Data_Green, HIGH);digitalWrite(Data_Red, HIGH);break;   //Orange
        }   
      } 
     else
     {
       digitalWrite(Data_Green, LOW);digitalWrite(Data_Red, LOW);
     }  
        digitalWrite(Clk, HIGH);
        digitalWrite(Clk, LOW); 
    }  
}

void ActivePulse()
{    

  digitalWrite(LE, HIGH); 
  digitalWrite(LE, LOW);
  digitalWrite(OE, LOW);
  flag_Oe=1;
}

void dot1_display_shift(unsigned char first,unsigned char second)
{
  static unsigned int i_cnt=0;    
  unsigned int buff1[16]={0};       //Dot1
  unsigned int buff2[16]={0};       //Dot2
            
  unsigned char high1=0;            //Dot1
  unsigned char low1=0;             //Dot1            
  unsigned char high2=0;            //Dot2
  unsigned char low2=0;             //Dot2

  register unsigned int i=0;
  
  for(i_cnt=0;i_cnt<16;i_cnt++){               
      if(move_motion==0)  
      {  
        buff1[i_cnt]=pgm_read_word(&string[first][i_cnt]);   // 1st String Dot1 stop
        buff2[i_cnt]=pgm_read_word(&string[second][i_cnt]);  // 2st String Dot2 stop
      }    
      if(move_motion==1)  
      {  
        if(i_cnt+up_cnt2>15)
        {
          buff1[i_cnt]=pgm_read_word(&string[first][i_cnt+up_cnt2-16]);   // 1st String Dot1 out
          buff2[i_cnt]=pgm_read_word(&string[second][i_cnt+up_cnt2-16]);  // 2st String Dot2 out
        }
        else
        {
          buff1[i_cnt]=pgm_read_word(&string[first+2][i_cnt+up_cnt2]);   // 1st String Dot1 in
          buff2[i_cnt]=pgm_read_word(&string[second+2][i_cnt+up_cnt2]);  // 2st String Dot2 in
        }   
      }      
  }   
                
  for(i=0;i<16;i++)
    { 
      high1=(buff1[i]>>8);
      low1=(buff1[i]&0xff);                 
      high2=(buff2[i]>>8);
      low2=(buff2[i]&0xff);

      shift_Register(low1);   
      shift_Register(high1);
      shift_Register(low2);   
      shift_Register(high2);       
                                                          
      row_dynamic();
      ActivePulse();
    }
}

void loop() {
  dot1_display_shift(Dot_char_cnt,Dot_char_cnt+1);  
  if(Dot_char_cnt==26){
   Dot_char_cnt=0; 
  }
}

The hard part will be translating the AVR hardware timer interrupt to something that works on the ESP32. The rest of the sketch should run on the ESP32 almost unchanged except for assigning ESP32 pin numbers.

You should probably change your 'string[]' to type 'uint16_t' since 'int' on the ESP32 is 32-bits and therefore twice as large as you need.

Looks like Timer2 is set for WGM 0 (simple counting) with the prescale set to 64 (16 MHz / 64 = 250 kHz). The timer count is set to 0xE7 after every overflow so it counts from 0xE7 to 0xFF (24 counts?). So about 10.417 kHz? You might be able to get away with executing the ISR code every 96 microseconds.

1 Like

ESP don't use PROGMEM, so your constant arrays should just be declared as 'const' and the compiler will place them in flash memory for you.

A 96uS timer ESP32

void IRAM_ATTR onTimer()
{
  BaseType_t xHigherPriorityTaskWoken;
your ISR trigger here
  //xEventGroupSetBitsFromISR(eg, OneMinuteGroup, &xHigherPriorityTaskWoken);
} // void IRAM_ATTR onTimer()
////
void setup()
{

  hw_timer_t * timer = NULL;
  timer = timerBegin( 3, 80, true );
  timerAttachInterrupt( timer, &onTimer, true );
  timerAlarmWrite(timer, 96, true);
  timerAlarmEnable(timer);
}

Uses hardware timer 4.

https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/index.html

#include <avr/pgmspace.h>
#include <avr/interrupt.h> 
#include <avr/io.h>

Does that mean I should use the 96uS timer you suggested instead of the hardware timer interrupt function in the code above?

Thank you for your reply. It's still difficult, but I know what to try.

thanks for the help

If you want.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.