How to convert from c to arduino


#include <pic18.h>
#include <htc.h>
#include <conio.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>

#define CLK_20MHZ 0
#define CLK_48MHZ 1
#define CLK_64MHZ 0

//Nothing in place for 20MHZ and 50 micro res. All other combos supported.
#define FIFTY_MICRO_RES 1
#define HUNDRED_MICRO_RES 0

__CONFIG(1,USBOSC & CPUDIV1 & PLLDIV12 & HS & FCMDIS & IESODIS);
__CONFIG(2,VREGDIS & PWRTDIS & BORDIS & WDTDIS);
__CONFIG(3,PBDIGITAL & LPT1DIS & MCLRDIS & ICPORTDIS & DEBUGDIS);
__CONFIG(4,STVREN & LVPDIS & XINSTDIS & DEBUGDIS);
__CONFIG(5,UNPROTECT);
__CONFIG(6,UNPROTECT);
__CONFIG(7,UNPROTECT);

// Data Structures
struct rowData
{
	unsigned char frameType; //0x01 = rowData
	unsigned int offTime; //time off in ms
	unsigned int onTime[24];
};

struct performanceData
{
	unsigned long num_loops;
	unsigned long micros;
};

//keeps track of timer2 with 50 or 100us resolution
unsigned int fifty_micros = 0;

//keeps track of timer0 with approx 3ms resolution
unsigned long micros = 0;

// Global variables
struct performanceData pData;
struct rowData rData;
unsigned char * p; //pointer for serial communication
unsigned char count;
unsigned char numSet;
unsigned char toWriteA;
unsigned char toWriteB;
unsigned char toWriteC;
unsigned char toWriteD;
int i;

// Interrupt service routine that is called every time a timer fires
void interrupt isr(void) {
	if(TMR2IF){
		//This is run every 50 or 100uS
		#if HUNDRED_MICRO_RES
		fifty_micros+=2;
		#endif
		#if FIFTY_MICRO_RES
		fifty_micros++;
		#endif
		TMR2IF=0; // clear event flag
	} else {
		if (TMR0IF) {
			//Run every 3ms or so
			//20MHz
			#if CLK_20MHZ
			micros += 3277;
			#endif
			#if CLK_48MHZ
			micros += 2731;
			#endif
			#if CLK_64MHZ
			micros += 2048;
			#endif
			TMR0IF=0;
		}
	}
}

void init(void){
	ADCON1 =0x06 ; // Changes PORTA to digital
	CMCON = 0x07 ; // Disable analog comparators
	//Configure ports, all output except for RC7
	TRISA = 0x00 ;
	TRISB = 0X00 ;
	TRISC = 0b10000000 ; //Set RC7 input for USART, all others output
	71
	TRISD = 0X00 ;
	TRISE = 0X00 ;
	PEIE = 1; //Peripheral interrupt enabled
	/***** Timer 2 Code ****
	* Prescale ratio set at 1:16
	* Timer2 module activated
	* Postscale ratio set at 1:10
	*/
	#if CLK_20MHZ
	T2CON = 0b00000101;
	//Set timer period to 97.6 = 122, works out to be ˜100uS
	//after ISR is run. OLD: 123, 125, 130 - micros too low,
	//120, 122, 123 to high. 124=dead on for 6.510215s
	//PR2 = 124;
	PR2 = 124;
	#endif
	#if CLK_48MHZ
	#if HUNDRED_MICRO_RES
	T2CON = 0b00000111; //1:16 prescaler
	PR2 = 74;
	#endif
	#if FIFTY_MICRO_RES
	T2CON = 0b00000101; //1:4 prescaler
	PR2 = 149;
	#endif
	#endif
	#if CLK_64MHZ
	T2CON = 0b00000111;
	#if HUNDRED_MICRO_RES
	PR2 = 99;
	#endif
	#if FIFTY_MICRO_RES
	PR2 = 49;
	#endif
	#endif
	//Timer0 Setup
	#if CLK_20MHZ
	T0CON = 0b11000101; //1:64 prescaler
	#endif
	#if CLK_48MHZ
	T0CON = 0b11000110; //1:128 prescaler
	#endif
	#if CLK_64MHZ
	72
	T0CON = 0b11000110; //1:128 prescaler
	#endif
	ei(); // Global interrupts enabled
	//Setup USART (Serial Port) for 19200bps
	#if CLK_20MHZ
	SPBRG = 64;
	#endif
	#if CLK_48MHZ
	SPBRG = 155;
	#endif
	#if CLK_64MHZ
	SPBRG = 207;
	#endif
	BRGH = 1; //Set to high speed mode
	TX9 = 0;
	SYNC = 0;
	SPEN = 1;
	TXEN = 1; //enable transmitter
	CREN = 1;
}
void turnOnPorts()
{
	//Dummy Data for Testing
	for (i = 0; i < 24; i++) {
		if (i % 2 == 0)
		{
			rData.onTime[i] = 60000;
		}
		else
		{
			rData.onTime[i] = 30000;
		}
	}
	//initialize variables
	count = 0;
	toWriteA = 0x0f;
	toWriteB = 0xff;
	toWriteC = 0x0f;
	toWriteD = 0xff;
	count = 0;
	//Loop through onTime data. If any is = 0,
	//indicate that pin should be turned off.
	while (count < 24)
	{
		if(rData.onTime[count] == 0) {
			if (count < 8)
			{
				toWriteB -= (1<<count);
			}
			if (count >= 8 && count < 16)
			{
				toWriteD -= (1<<(count-8));
			}
			if (count >= 16 && count < 20)
			{
				//PORTA0-PORTA3
				toWriteA -= (1<<(count-16));
			}
			if (count >= 20)
			{
				//PORTC0-PORTC3
				toWriteC -= (1<<(count-20));
			}
		}
		count++;
	}
	//Keep track of how many are turned off already
	for (i = 0; i < 24; i++) {
		if (rData.onTime[i] == 0x0000)
		{
		numSet++;
		}
	}
	//Write the calculated values to the ports
	PORTA = toWriteA;
	PORTB = toWriteB;
	PORTC = toWriteC;
	PORTD = toWriteD;
}

void turnOffPorts()
{
	//Keep track of performance for debugging and optimizations
	pData.num_loops = 0;
	numSet = 0;
	//Initialize
	toWriteA = 0x0f;
	toWriteB = 0xff;
	toWriteC = 0x0f;
	toWriteD = 0xff;
	//About 1uS has passed since the ports were initialized.
	//Set to 0 for performance testing with the stopwatch function.
	TMR2 = 0;
	fifty_micros = 0;
	74
	//Performance sensitive loop
	while(numSet < 24)
	{
		count = 0;
		while (count < 24)
		{
			if((rData.onTime[count] != 0x0000) &&
			(rData.onTime[count] <= fifty_micros))
			{
				numSet++;
				rData.onTime[count] = 0x0000;
				if (count < 8)
				{
					toWriteB -= (1<<count);
				}
				if (count >= 8 && count < 16)
				{
					toWriteD -= (1<<(count-8));
				}
				if (count >= 16 && count < 20)
				{
					//PORTA0-PORTA3
					toWriteA -= (1<<(count-16));
				}
				if (count >= 20)
				{
					//PORTC0-PORTC3
					toWriteC -= (1<<(count-20));
				}
			}
			count++;
		}
		PORTA = PORTA & toWriteA;
		PORTB = PORTB & toWriteB;
		PORTC = PORTC & toWriteC;
		PORTD = PORTD & toWriteD;
		pData.num_loops++; //performance measure.
	}
	//Comments regarding different optimizations tried
	//START w/ nested for loops:
	//t = 15.3014mS, micros 15400, shifter=74
	//
	//ONE LOOP:
	//t = 15.328, micros 15400, shifter = 79
	//WITH 2 SUBPORTS and nested ifs
	//t = 15.185, micros 15400, shifter = 78
	//WITH 2 subport and non-nested ifs
	//t=15.249, micros 15300, shifter = 78
	//WITH 2 subport and non-nested ifs and count shifter instead of j
	//t=15.324, micros 15400, shifter = 79
	pData.micros = micros;
	//48MHZ = 263 loops, 15.2466s = 0.05797ms
	75
	//64MHZ = 351 loops, 15.1642s = 0.0432ms
	//64MHZ = 347 loops, 15.1359s = 0.0436ms @ 50uS resolution
	//64MHZ = 413 loops, 15.1479s = 0.0367ms @ 50uS and changing
	// fifty_micros variable to int rather than long
	//48MHZ = 308 loops, 15.1769s = 0.0492ms @ 50uS and
	// the int rather than long
}

//Serial USART functions -- grabbed from Hi-Tech C examples folder
void putch(unsigned char byte)
{
	/* output one byte */
	while(!TXIF) /* set when register is empty */
	continue;
	TXREG = byte;
}

unsigned char getch() {
	/* retrieve one byte */
	while(!RCIF) /* set when register is not empty */
	continue;
	return RCREG;
}

//Writes contents of rData to the serial port
void writeRowDataInfo()
{
	p = &rData;
	i = 0;
	while(i < sizeof(rData))
	{
		putch(*p);
		i++;
		p++;
	}
}

void writePerformanceData()
{
	p = &pData;
	i = 0;
	while(i < sizeof(pData))
	{
		putch(*p);
		i++;
		p++;
	}
}

//Reads serial port to fill in rData
void readRowDataInfo()
{
	putch(0x06); //Send ACK character so that PC knows to start sending data.
	p = &rData;
	i = 0;
	while(i < sizeof(rData))
	{
		*p = getch();
		p++;
		i++;
	}
}

main()
{
	//Initializes ports, timers, usart
	init();
	//Turn off timer2, turn on timer0, clear micros counter
	TMR0ON = 1;
	TMR0IE = 1;
	TMR2ON = 0;
	TMR2IE = 0;
	TMR0 = 0; //Reset timer 0

	while(1) {
		micros = 0;
		//Read next row from serial port
		readRowDataInfo();

		//Turn on all pins required
		turnOnPorts();

		//Turn off pins when the timing is correct (performance sensitive area)
		turnOffPorts();

		//Wait for offTime period
		while (micros < rData.offTime)
		{
			//busy loop
		}
	}
}

That code is very specific for a PIC processor, and quite a bit of effort would be required to modify it to run on any other type of processor.

What other processor did you have in mind?

I have a program that works but maybe there are problems at the time of so for a commitment to this code

if you have code for a PIC18 have a look at Microchip curiosity nano development boards which include several PIC18 boards.
Because your code is so PIC18 specific if you do have to use an Arduino the simplest approach is probably to get a specification of the product and implement it from scratch.

Here you go. All you have to do is convert the PIC-specific code to AVR code. Looks like most of it is timers, Serial, and maybe an analog to digital converter.

Note: The code appears to be using 24 output pins. This will need something with more pins than an UNO/Nano. Perhaps an Arduino MEGA?

byte TMR2IF = 0;
byte TMR0IF = 0;

// #include <pic18.h>
// #include <htc.h>
// #include <conio.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>

#define CLK_20MHZ 0
#define CLK_48MHZ 1
#define CLK_64MHZ 0

//Nothing in place for 20MHZ and 50 micro res. All other combos supported.
#define FIFTY_MICRO_RES 1
#define HUNDRED_MICRO_RES 0

//__CONFIG(1, USBOSC & CPUDIV1 & PLLDIV12 & HS & FCMDIS & IESODIS);
//__CONFIG(2, VREGDIS & PWRTDIS & BORDIS & WDTDIS);
//__CONFIG(3, PBDIGITAL & LPT1DIS & MCLRDIS & ICPORTDIS & DEBUGDIS);
//__CONFIG(4, STVREN & LVPDIS & XINSTDIS & DEBUGDIS);
//__CONFIG(5, UNPROTECT);
//__CONFIG(6, UNPROTECT);
//__CONFIG(7, UNPROTECT);

// Data Structures
struct rowData
{
  unsigned char frameType; //0x01 = rowData
  unsigned int offTime; //time off in ms
  unsigned int onTime[24];
};

struct performanceData
{
  unsigned long num_loops;
  unsigned long microseconds;
};

//keeps track of timer2 with 50 or 100us resolution
unsigned int fifty_microseconds = 0;

//keeps track of timer0 with approx 3ms resolution
unsigned long microseconds = 0;

// Global variables
struct performanceData pData;
struct rowData rData;
unsigned char * p; //pointer for serial communication
unsigned char count;
unsigned char numSet;
unsigned char toWriteA;
unsigned char toWriteB;
unsigned char toWriteC;
unsigned char toWriteD;
int i;

// Interrupt service routine that is called every time a timer fires
void TimerISR(void)
{
  if (TMR2IF)
  {
    //This is run every 50 or 100uS
#if HUNDRED_MICRO_RES
    fifty_microseconds += 2;
#endif
#if FIFTY_MICRO_RES
    fifty_microseconds++;
#endif
    TMR2IF = 0; // clear event flag
  }
  else
  {
    if (TMR0IF)
    {
      //Run every 3ms or so
      //20MHz
#if CLK_20MHZ
      microseconds += 3277;
#endif
#if CLK_48MHZ
      microseconds += 2731;
#endif
#if CLK_64MHZ
      microseconds += 2048;
#endif
      TMR0IF = 0;
    }
  }
}

void init(void)
{
  //  ADCON1 = 0x06 ; // Changes PORTA to digital
  //  CMCON = 0x07 ; // Disable analog comparators
  //Configure ports, all output except for RC7
  //  TRISA = 0x00 ;
  //  TRISB = 0X00 ;
  //  TRISC = 0b10000000 ; //Set RC7 input for USART, all others output
  // 71;
  //  TRISD = 0X00 ;
  //  TRISE = 0X00 ;
  //  PEIE = 1; //Peripheral interrupt enabled
  /***** Timer 2 Code ****
    Prescale ratio set at 1:16
    Timer2 module activated
    Postscale ratio set at 1:10
  */
#if CLK_20MHZ
  T2CON = 0b00000101;
  //Set timer period to 97.6 = 122, works out to be ˜100uS
  //after ISR is run. OLD: 123, 125, 130 - microseconds too low,
  //120, 122, 123 to high. 124=dead on for 6.510215s
  //PR2 = 124;
  PR2 = 124;
#endif
#if CLK_48MHZ
#if HUNDRED_MICRO_RES
  T2CON = 0b00000111; //1:16 prescaler
  PR2 = 74;
#endif
#if FIFTY_MICRO_RES
  //  T2CON = 0b00000101; //1:4 prescaler
  //  PR2 = 149;
#endif
#endif
#if CLK_64MHZ
  T2CON = 0b00000111;
#if HUNDRED_MICRO_RES
  PR2 = 99;
#endif
#if FIFTY_MICRO_RES
  PR2 = 49;
#endif
#endif
  //Timer0 Setup
#if CLK_20MHZ
  T0CON = 0b11000101; //1:64 prescaler
#endif
#if CLK_48MHZ
  //  T0CON = 0b11000110; //1:128 prescaler
#endif
#if CLK_64MHZ
//  72
  T0CON = 0b11000110; //1:128 prescaler
#endif
  interrupts();  // ei(); // Global interrupts enabled
  //Setup USART (Serial Port) for 19200bps
#if CLK_20MHZ
  SPBRG = 64;
#endif
#if CLK_48MHZ
  //  SPBRG = 155;
#endif
#if CLK_64MHZ
  SPBRG = 207;
#endif
  //  BRGH = 1; //Set to high speed mode
  //  TX9 = 0;
  //  SYNC = 0;
  //  SPEN = 1;
  //  TXEN = 1; //enable transmitter
  //  CREN = 1;
}

void turnOnPorts()
{
  //Dummy Data for Testing
  for (i = 0; i < 24; i++)
  {
    if (i % 2 == 0)
    {
      rData.onTime[i] = 60000;
    }
    else
    {
      rData.onTime[i] = 30000;
    }
  }
  //initialize variables
  count = 0;
  toWriteA = 0x0f;
  toWriteB = 0xff;
  toWriteC = 0x0f;
  toWriteD = 0xff;
  count = 0;
  //Loop through onTime data. If any is = 0,
  //indicate that pin should be turned off.
  while (count < 24)
  {
    if (rData.onTime[count] == 0)
    {
      if (count < 8)
      {
        toWriteB -= (1 << count);
      }
      if (count >= 8 && count < 16)
      {
        toWriteD -= (1 << (count - 8));
      }
      if (count >= 16 && count < 20)
      {
        //PORTA0-PORTA3
        toWriteA -= (1 << (count - 16));
      }
      if (count >= 20)
      {
        //PORTC0-PORTC3
        toWriteC -= (1 << (count - 20));
      }
    }
    count++;
  }
  //Keep track of how many are turned off already
  for (i = 0; i < 24; i++)
  {
    if (rData.onTime[i] == 0x0000)
    {
      numSet++;
    }
  }
  //Write the calculated values to the ports
  //  PORTA = toWriteA;
  PORTB = toWriteB;
  PORTC = toWriteC;
  PORTD = toWriteD;
}

void turnOffPorts()
{
  //Keep track of performance for debugging and optimizations
  pData.num_loops = 0;
  numSet = 0;
  //Initialize
  toWriteA = 0x0f;
  toWriteB = 0xff;
  toWriteC = 0x0f;
  toWriteD = 0xff;
  //About 1uS has passed since the ports were initialized.
  //Set to 0 for performance testing with the stopwatch function.
  //  TMR2 = 0;
  fifty_microseconds = 0;
  // 74;
  //Performance sensitive loop
  while (numSet < 24)
  {
    count = 0;
    while (count < 24)
    {
      if ((rData.onTime[count] != 0x0000) &&
          (rData.onTime[count] <= fifty_microseconds))
      {
        numSet++;
        rData.onTime[count] = 0x0000;
        if (count < 8)
        {
          toWriteB -= (1 << count);
        }
        if (count >= 8 && count < 16)
        {
          toWriteD -= (1 << (count - 8));
        }
        if (count >= 16 && count < 20)
        {
          //PORTA0-PORTA3
          toWriteA -= (1 << (count - 16));
        }
        if (count >= 20)
        {
          //PORTC0-PORTC3
          toWriteC -= (1 << (count - 20));
        }
      }
      count++;
    }
    //    PORTA = PORTA & toWriteA;
    PORTB = PORTB & toWriteB;
    PORTC = PORTC & toWriteC;
    PORTD = PORTD & toWriteD;
    pData.num_loops++; //performance measure.
  }
  //Comments regarding different optimizations tried
  //START w/ nested for loops:
  //t = 15.3014mS, microseconds 15400, shifter=74
  //
  //ONE LOOP:
  //t = 15.328, microseconds 15400, shifter = 79
  //WITH 2 SUBPORTS and nested ifs
  //t = 15.185, microseconds 15400, shifter = 78
  //WITH 2 subport and non-nested ifs
  //t=15.249, microseconds 15300, shifter = 78
  //WITH 2 subport and non-nested ifs and count shifter instead of j
  //t=15.324, microseconds 15400, shifter = 79
  pData.microseconds = microseconds;
  //48MHZ = 263 loops, 15.2466s = 0.05797ms
  // 75;
  //64MHZ = 351 loops, 15.1642s = 0.0432ms
  //64MHZ = 347 loops, 15.1359s = 0.0436ms @ 50uS resolution
  //64MHZ = 413 loops, 15.1479s = 0.0367ms @ 50uS and changing
  // fifty_microseconds variable to int rather than long
  //48MHZ = 308 loops, 15.1769s = 0.0492ms @ 50uS and
  // the int rather than long
}

//Serial USART functions -- grabbed from Hi-Tech C examples folder
void putch(unsigned char c)
{
  (void) c;
  /* output one byte */
  //  while (!TXIF) /* set when register is empty */
  //    continue;
  //  TXREG = c;
}

unsigned char getch()
{
  /* retrieve one byte */
  //  while (!RCIF) /* set when register is not empty */
  //    continue;
  //  return RCREG;
  return 0;
}

//Writes contents of rData to the serial port
void writeRowDataInfo()
{
  p = (byte *) &rData;
  size_t i = 0;
  while (i < sizeof(rData))
  {
    putch(*p);
    i++;
    p++;
  }
}

void writePerformanceData()
{
  p = (byte *) &pData;
  size_t i = 0;
  while (i < sizeof(pData))
  {
    putch(*p);
    i++;
    p++;
  }
}

//Reads serial port to fill in rData
void readRowDataInfo()
{
  putch(0x06); //Send ACK character so that PC knows to start sending data.
  p = (byte *) &rData;
  size_t i = 0;
  while (i < sizeof(rData))
  {
    *p = getch();
    p++;
    i++;
  }
}

void setup()
{
  //Initializes ports, timers, usart
  init();
  //Turn off timer2, turn on timer0, clear microseconds counter
  //  TMR0ON = 1;
  //  TMR0IE = 1;
  //  TMR2ON = 0;
  //  TMR2IE = 0;
  //  TMR0 = 0; //Reset timer 0
}

void loop()
{
  microseconds = 0;
  //Read next row from serial port
  readRowDataInfo();

  //Turn on all pins required
  turnOnPorts();

  //Turn off pins when the timing is correct (performance sensitive area)
  turnOffPorts();

  //Wait for offTime period
  while (microseconds < rData.offTime)
  {
    //busy loop
  }
}

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