//Pins
const int acq_led_pin = PB5; //D13-->PB5
const int acqPB = PIND2; //D2-->PD2
const int acq_sw = 2;
//Counter and compare values
//Timer Prescaler 1 --> fclk=16MHz
//CS12,CS11,CS10 101 100 011 010 001 TCCR1B
//Prescaler 1024 256 64 8 ***1***
//fclk 15.625kHz 62.5kHz 250kHz 2MHz ***16MHz***
//Tclk 64us 16us 4us 0.5us 62.5ns
//t1_comp
//1000Hz 1ms 15.625 62.5 250 2000 16000
//500Hz 2ms 31.250 125 500 4000 ***32000***
//250Hz 4ms 62.500 250 1000 8000 64000
const uint16_t t1_load = 0;
//const uint16_t t1_comp = 32000;//500Hz; 2ms sampling rate
const uint16_t t1_comp = 64000;//250Hz; 4ms sampling rate
//volatile unsigned long samples = 0;
//const uint16_t fs=500;//Hz
const uint16_t fs=250;//Hz
const uint8_t fsLow=lowByte(fs);
const uint8_t fsHigh=highByte(fs);
const uint16_t acqtime = 30; //seconds Acq time
const uint8_t acqTimeLow=lowByte(acqtime);
const uint8_t acqTimeHigh=highByte(acqtime);
unsigned long maxSamples = acqtime * fs; //500samples/sec --> 2ms/samp
volatile bool flgSyncSent = false; //byte string sent
//===================Setup==============================================================================
void setup() {
Serial.begin(9600);//115200
LED_Init();
timer_init();
ADC_INIT();
//ADCSRA |= 1 << ADSC; //Start first conversion
//Serial.println("Initialization Finished");
//Serial.println(LED_BUILTIN);
//Serial.write(0x41);
// Serial.write(0x42);
//Serial.print("fsHigh : ");Serial.println(fsHigh,HEX);
//Serial.print("fsLow : ");Serial.println(fsLow,HEX);
//Serial.print("acqTimeHigh: ");Serial.println(acqTimeHigh,HEX);
//Serial.print("acqTimeLow: ");Serial.println(acqTimeLow,HEX);
}//End setup()
//=========================================Subroutines==================================================
//-----------------------------LED INIT---------------------------------------------------------------
void LED_Init() {
//--------------------PORTB----------------------------------------------------------------------------
// PORTB – The Port B Data Register (spec 13.4.2)
//b7 b6 b5 b4 b3 b2 b1 b0
//PB7 PB6 PB5 PB4 PB3 PB2 PB1 PB0
//OSC2 OSC1 D13 D12 D11 D10 D9 D8
//0 0 0 0 0 0 0 0 1: Input Pin w/ pullup 0: Output
// acq_led_pin
//DDRB: Port B Data Direction Register (spec 13.4.3)
//b7 b6 b5 b4 b3 b2 b1 b0
//DDB7 DDB6 DDB5 DDB4 DDB3 DDB2 DDB1 DDB0
//OSC2 OSC1 D13 D12 D11 D10 D9 D8
//0 0 1 1 0 0 0 0 1: Output 0: Input
//PINB: Port B Input Pins Address (spec 13.4.4)
//b7 b6 b5 b4 b3 b2 b1 b0
//PINB7 PINB6 PINB5 PINB4 PINB3 PINB2 PINB1 PINB0
//OSC2 OSC1 D13 D12 D11 D10 D9 D8
//-----------------PORTC-------------------------------------------------------------------------------
// PORTC – The Port C Data Register (spec 13.4.5)
//b7 b6 b5 b4 b3 b2 b1 b0
//PC7 PC6 PC5 PC4 PC3 PC2 PC1 PC0
//- RESET A5 A4 A3 A2 A1 A0
//0 0 0 0 0 0 0 0 1: Input Pin w/ pullup 0: Output
//DDRC: Port C Data Direction Register (spec 13.4.6)
//b7 b6 b5 b4 b3 b2 b1 b0
//DDC7 DDC6 DDC5 DDC4 DDC3 DDC2 DDC1 DDC0
//- RESET A5 A4 A3 A2 A1 A0
//0 0 1 1 0 0 0 0 1: Output 0: Input
//PINC: Port C Input Pins Address (spec 13.4.7)
//b7 b6 b5 b4 b3 b2 b1 b0
//PINC7 PINC6 PINC5 PINC4 PINC3 PINC2 PINC1 PINC0
//- RESET A5 A4 A3 A2 A1 A0
//------------------PORTD--------------------------------------------------------------------------------
//PORTD – The Port D Data Register (spec 13.4.8)
//b7 b6 b5 b4 b3 b2 b1 b0
//PD7 PD6 PD5 PD4 PD3 PD2 PD1 PD0
//D7 D6 D5 D4 D3 D2 D1 D0
//0 0 0 0 0 1 0 0 1: Input Pin w/ pullup 0: Output
// acqPB
//DDRD: Port D Data Direction Register (spec 13.4.9)
//b7 b6 b5 b4 b3 b2 b1 b0
//DDD7 DDD6 DDD5 DDD4 DDD3 DDD2 DDD1 DDD0
//D7 D6 D5 D4 D3 D2 D1 D0
//0 0 0 0 0 0 0 0 1: Output 0: Input
//PIND: Port D Input Pins Address (spec 13.4.10)
//b7 b6 b5 b4 b3 b2 b1 b0
//PIND7 PIND6 PIND5 PIND4 PIND3 PIND2 PIND1 PIND0
//D7 D6 D5 D4 D3 D2 D1 D0
//--------------------------------------------------------------------------------------------------------
DDRB = 0b00100000;
PORTB = 0b00000000;//Set output low to turn off on board LED
DDRD = 0b00000000;
PORTD = 0b00000100;
}
//-------------------------------------Timer Counter Setup----------------------------------------------
void timer_init() {
//SREG: AVR Status Register
//b7 b6 b5 b4 b3 b2 b1 b0
//I T H S V N Z C
//1
//TCCR1A: Timer Counter Control Reg 1A (spec 15.11.1)
//b7 b6 b5 b4 b3 b2 b1 b0
//COM1A1 COM1A0 COM1B1 COM1B0 - - WGM11 WGM10
//0 0 0 0 0 0 0 0 CTC,
//TCCR1B: Timer Counter Control Reg 1B (spec 15.11.2)
//b7 b6 b5 b4 b3 b2 b1 b0
//ICNC1 ICES1 - WGM13 WGM12 CS12 CS11 CS10
// 0 0 0 0 1 0 0 1 CTC Mode, fclk/1 ==16MHz
//TIMSK1: Timer/counter1 Interrupt Mask Register (spec 15.11.8)
//b7 b6 b5 b4 b3 b2 b1 b0
//- - ICIE1 - - OCIE1B OCIE1A TOIE1
//0 0 0 0 0 0 1 0 Interruot on output compare 1A
//SREG=0b10000000;//Global Interrupt Enable (SEI() -->I=1; CLI()--->I=0)
TCNT1 = 0; //Init Timer/Counter1 Register
TCCR1A = 0b00000000;
TCCR1B = 0b00001001;
TIMSK1 = 0b00000010;
OCR1A = t1_comp;//
sei();
}//timer_init()
//--------------------------------------ADC Setup-------------------------------------------------------
void ADC_INIT() {
//ADCSRA: ADC Control and Status Register A (Spec 23.9.2)
//b7 b6 b5 b4 b3 b2 b1 b0
//ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0
//1 0 0 0 0 1 1 1
//ADC Enable. Auto Trigger off, fadc,clk=fclk/128 =125kHz
//ADCSRB: ADC Control and Status Register B (Spec 23.9.4)
//b7 b6 b5 b4 b3 b2 b1 b0
//- ACME - - - ADTS2 ADTS1 ADTS0
//1 0 0 0 0 0 0 0 Free Run Mode
//ADMUX: ADC Multiplexer Selection Register (Spec 23.9.1)
//b7 b6 b5 b4 b3 b2 b1 b0
//REFS1 REFS0 ADLAR - MUX3 MUX2 MUX1 MUX0
//0 1 0 0 0 0 0 1 AREF, A0 input
ADCSRA = 0b10000111;
ADCSRB = 0b00000000;
ADMUX = 0b01000000;
ADCSRA |= 1 << ADSC; //Start first conversion
}//END ADC_INIT()
//-------------------------------------Send Sync--------------------------------------------------
void sendSync(bool j) {
static byte sync[2][6] = {{0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, {0x55, 0x55, 0x55, 0x55, 0x55, 0x55}};
//Serial.print("flgSyncSent 1: ");Serial.println(flgSyncSent);
static byte buff[10]={0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, fsLow, fsHigh, acqTimeLow, acqTimeHigh};
if (flgSyncSent == false) {
// Serial.print("Serial.availableForWrite(): ");Serial.println(Serial.availableForWrite());
Serial.write(buff,10);
/*
for (int i = 0; i <= 9; i++) {
//Serial.write(sync[i]);
Serial.println(buff[i]);
}//End for
*/
flgSyncSent = true;
}
//Serial.print("flgSyncSent 2: ");Serial.println(flgSyncSent);
}
//-------------------------------------ALT ADC Read----------------------------------------------
int16_t adc_read(byte channel, bool j) {
//Select ADC Channel
ADMUX &= 0b11110000;
ADMUX |= channel;
//Serial.println(ADMUX, HEX);
ADCSRA |= (1 << ADSC); //Start Conversion
sendSync(j);
//Wait for conversion to complete
while (bitRead(ADCSRA, ADSC) == 1) {
// Serial.println("wait");
}
// Serial.print("Serial.availableForWrite() 2: ");Serial.println(Serial.availableForWrite());
//byte buff[2]={ADCH,ADCL};//Big Endian
byte buff[2]={ADCL,ADCH};//little Endian
Serial.write(buff,2);
// Serial.write(ADCH);//Send MSB
// Serial.write(ADCL);// Send LSB
return ADCL | (ADCH << 8);
}//END adc_read()
//===============================Loop==================================================================
void loop() {
delay(10);//Fake do something
}
//=======================ISR======================================
ISR(TIMER1_COMPA_vect) {
// Serial.println("ISR(TIMER1_COMPB_vect)");
static unsigned long samples = 0;
static byte numPbPress = 0;
static bool flgAcqEcg = false;
int pBpress;
int16_t val;
if ((flgAcqEcg == 1) && (samples <= maxSamples)) {
val = adc_read(0, 0); //Mux channel 0; sync j 0xAA
//Serial.println(val);
//Serial.write(val);
samples++;
}
//Serial.print("samples: ");Serial.println(samples);
//pBpress = PIND & (1 << acqPB); //Read State of Acq pushbutton
//pBpress = pBpress >> acqPB; //Extrat Bit
pBpress = (PIND & (1 << acqPB)) >> acqPB; // Read State of Acq pushbutton and Extracy Bit
if (pBpress == 0) {
numPbPress += 1;
} else {
numPbPress = 0;
}
if (numPbPress == 5) {
flgAcqEcg = !flgAcqEcg;//Toggle flg
//if (flgAcqEcg == false) {
// flgSyncSent = false;
// sendSync(1);//Send 0x55 sync
// flgSyncSent = false;
// }
PORTB ^= (1 << acq_led_pin);
}
if (samples >= maxSamples) {
flgAcqEcg = false;
//flgSyncSent = false;
//sendSync(1);//Send 0x55 sync
//flgSyncSent = false;
PORTB &= ~(1 << acq_led_pin);
samples = 0;
}
//Serial.print("flgSyncSent 3: ");Serial.println(flgSyncSent);
//Serial.print("availableForWrite(): "); Serial.println( Serial.availableForWrite());
//Serial.print("numPbPress: "); Serial.println(numPbPress);
// Serial.print("PIND2: ");Serial.println(PIND2,HEX);
//Serial.print("PIND: ");Serial.println(PIND,HEX);
//Serial.print("pBpress: ");Serial.println(pBpress);
}// END ISR