Converting a code from AVR to arduino

Hi everyone, I am relatively new to Arduino and about programming I have some experience with Python but nothing with C or C++

I found this code online and wanted modify it so I can upload it on Arduino IDE. I understand part of the code but when it comes to registers and stuff I am lost.
The code is for SpO2 and heart beat monitor.

Could someone help me understand and modify this code or guide me to resources where I teach myself to comprehend it..
Any help will be appreciated :slight_smile:

Following is code explanation as mentioned on site:
The program design consist of a few major parts. The samples are read in by using the built-in analog to digital converter (ADC) on the mega644. It performs a 10 bit analog to digital conversion based on a reference voltage (Aref). In this project, as the circuit ran on approximately five volt Vcc, so Aref was set to five volts. We know that ADC data registers are ADCH and ADCL, which are 8 bit individually and give a 16 bit register when used together. As the ADC in Atmega644 is a 10 bit ADC, he will give out only 10 bit of digital value. Since the least two significant bits of the ADC do not significantly affect the design, it has been ignored and the data has been stored in ADCH only. Twice of memory needs to be allocated, which cannot be afforded. To read two values from the ADC when needed, one would be read, then the ADMUX register changed to the other input, and then the program waited until the second conversion was complete. Due to these factors, I decided to use the ADCH register to store the 8 bit data. The analog signal is given to the default A0 pin of the microcontroller. The prescalar of the ADC is set to 128, giving us a frequency of 125KHz, very much in the ADC frequency range of 50-200KHz. The ADC is set in free running mode. Timer 1 is a 16 bit timer/counter and has been used to perform interrupts every 0.01 second. As the frequency of the heart rate is about 1.2 Hz, 1/100 of that is chosen as appropriate for ADC to sample. Thus prescalar of 1024 has been selected in clear timer on compare (CTC) mode.
Calculations:
Required delay = 0.01 seconds
Clock = 16MHz
Prescalar = 1024
Thus, New frequency = Clock/Prescalar = 15625Hz
Timer count = (Required delay/Delay after prescaling)-1
= (0.01/(1/15625))-1
=155
Thus OCR1A is loaded with 155 and TCNT1 is initialized to zero. As the timer starts, TCNT1 will start counting up to 155, and on 155, an interrupt will be generated and ISR will be executed. As the ISR is generated due to timer1 compare, it is called as ISR(TIMER1_COMPA_vect). UART has also been initialized to have a serial communication between the computer and the microcontroller. The Maximum voltage and the minimum voltage is required to be calculated to find out the average as well as the ratio. The average is inturn used to determine the heart rate by counting the number of average crossings. The average is initially initialized to 60, a value determined by experimenting for the readings on a couple of people. 60 is a fairly constant value for almost every person's reading, i.e. a 60 on ADC is about 1.17V. Thus a crossing will be detected at every average value. The ISR will be executed every 0.01 second, and in ISR, we start loading the value of count in a variable lastcount, so that we have the value of current count as well as previous count all time. Then, as we know that ADCH has the 8 bit digital data, its value is loaded into the count. For checking and determining the maximum and the minimum voltage, we start comparing the maximum voltage (Pre initialized to 0) and the minimum voltage (Pre initialized to 255) with the value of the count, and start upgrading their values. Now, to determine the values of maximum voltage, minimum voltage, average and heart rate in a set period, we need to incorporate average crossing, and on having every average crossing, a variable c is incremented and loaded into d. Variable d is thus the number of ISRs executed. We know that time for one ISR is 0.01 seconds, thus frequency = 1/(0.01d), and heart rate per minute is 60frequency. Also, after determining the maximum and minimum voltages, the ratio x is calculated and used in the SpO2 formula to give its value.
$)

#define F_CPU 16000000UL //16MHz crystal

#include <inttypes.h>

#include <avr/io.h>

#include <avr/interrupt.h>

#include <stdio.h>

#include <avr/eeprom.h>

#include <util/delay.h>

#include <stdlib.h>

#include <string.h>

#include <avr/pgmspace.h>

#include "uart.h" // serial communication library

#include "lcd_lib.h" //lcd library

const int8_t LCD_initialize[] PROGMEM ="\0";

int8_t lcd_buffer[17]; // LCD display buffer

int8_t lcd_buffer1[17]; // LCD display buffer

FILE uart_str = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW); //UART initialization

volatile int max, min,a,b,count,c,d,average,lastcount;

float HeartRate,Vmax,Vmin,x,y,z;

float value=0.0158;

void timer1_init()

{

TCCR1B |= (1 << WGM12)|(1 << CS12)|(0 << CS11)|(1 << CS10); // set up timer with prescaler = 1024 and CTC mode

TCNT1 = 0; // initialize counter

OCR1A = 155; // initialize compare value

TIMSK1 |= (1 << OCIE1A); // enable compare interrupt

}

void init_lcd(void)

{

LCDinit(); //initialize the display

LCDcursorOFF(); //no cursor

LCDclr(); //clear the display

LCDGotoXY(0,0); //go to x and y position on the lcd

CopyStringtoLCD(LCD_initialize, 0, 0);

}

int main()

{

ADMUX= (0<<REFS1)|(1<<REFS0)|(1<<ADLAR); //AVcc as reference voltage and Left shift bits

ADCSRA=(1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)| (1<<ADATE); //Prescalar 128 and set bit for free running mode

ADCSRB= (0<<ADTS2)|(0<<ADTS1)|(0<<ADTS0); //Free running mode

init_lcd();

timer1_init(); //timer 1 initialization

average=60; //initialize average value for average crossing detection

max = 0; //initialize maximum =0

min = 255; //initialize minimum = 255

sei(); //Global interrupt enable

UCSR0B = _BV(TXEN0); //Serial transmission

UBRR0 = 103;

ADCSRA |= 1<<ADSC; //start conversion

stdout = stdin = stderr = &uart_str; //UART transmission

LCDclr(); //clear lcd

CopyStringtoLCD(LCD_initialize, 0, 0); //copy the string data to position x=0, position y=0

while (1)

{

z=1/(0.01*d); //calculation of frequency of ISR

HeartRate=z*60; //calculation of heart rate (beats per min)

fprintf(stdout,"HeartRate=%f \n",HeartRate); //UART transmission of heart rate

CopyStringtoLCD(LCD_initialize, 0, 0);

_delay_ms(2000);

sprintf(lcd_buffer,"HeartRate=%2.0f ",HeartRate); //sending heart rate values to lcd for display

LCDGotoXY(0, 0); // goto position x=0, position y=0

LCDstring(lcd_buffer, strlen(lcd_buffer));

sprintf(lcd_buffer1,"SP02=%f ",y); //sending SpO2 values to lcd for display

LCDGotoXY(0, 1); // goto position x=0, position y=1 (second row)

LCDstring(lcd_buffer1, strlen(lcd_buffer));

PORTD=0b00000001; //blinking led every 4 ms

_delay_ms(4);

PORTD=0b00000000;

_delay_ms(4);

PORTD=0b00000010;

_delay_ms(4);

PORTD=0b00000000;

_delay_ms(4);

}

}

ISR(TIMER1_COMPA_vect)

{

lastcount=count; // copying value of count into last count used for average crossing (becomes previous value_

count = ADCH; //copying value of ADCH into count (current value)

//we checking for maximum and minimum value for analog input

if(count>max)

{

max=count; //if current value in count is greater than maximum value, then copy it to maximum

}

else if (count<min)

{

min=count; //if current value in count is less than minimum value, then copy it to minimum

}

c++; //counter increments

if((lastcount>average) && (count<average)) //average crossing condition

{

average=((max+min)/2); //average calculation

a=max;

b=min;

fprintf(stdout,"a=%i\n",a); //UART transmission

fprintf(stdout,"b=%i\n",b);

x=value/(a-b); //calculation of ratio

fprintf(stdout,"x=%f\n",x);

y=(10.0002*x*x*x)-(52.887*x*x)+(26.871*x)+98.283; //calculation of SpO2

fprintf(stdout,"y=%f\n",y);

d=c; //copy counter value to d

c=0; //clear counter

fprintf(stdout,"d=%i\n",d);

max=0; //clear max

min=255; //clear min

}}

It might be easier to say what you want the program to do and just write a new Arduino program.

...R

that actually makes sense, thanks mate :wink: