I am working on an ultrasound device. We want to generate a particular signal to drive the 1 MHz piezoelectric sensor at various resonance frequencies point.
The goal is to write a code using Atmega328p (Arduino Nano) to generate a signal with 8 fixed-width pulses with varying intervals as seen in the table below.
The sample of the signal we are looking for is below: the yellow signal
I succeeded to find a code to generate an 8 pulses signal at the unique frequency of 1MHz: The code and the results on the oscilloscope are found below:
#define NOP __asm__ __volatile__ ("nop\n\t") void delayMilliseconds(int ms) { for (int i = 0; i < ms; i++) { delayMicroseconds(1000); } } void stopTransducer() { cli(); TCCR1B = 0; sei(); } void startTransducer(float freq, float dutyCycle) { dutyCycle = dutyCycle * 10.0; if (dutyCycle == 0) dutyCycle = 0.0; else if (dutyCycle == 1.0) dutyCycle = 0.1; else if (dutyCycle == 2.0) dutyCycle = 0.2; else if (dutyCycle == 3.0) dutyCycle = 0.3; else if (dutyCycle == 4.0) dutyCycle = 0.4; else if (dutyCycle == 5.0) dutyCycle = 0.5; else if (dutyCycle == 6.0) dutyCycle = 0.6; else if (dutyCycle == 7.0) dutyCycle = 0.7; else if (dutyCycle == 8.0) dutyCycle = 0.8; else if (dutyCycle == 9.0) dutyCycle = 0.9; cli(); TCCR1B = _BV(WGM13) | _BV(CS10) | _BV(ICNC1); //f0 = fclk / (2 * N * Top) long topv = (long) ((float) F_CPU / (freq * 2.0 * 1.0)); ICR1 = topv; //OCR1A = 4; OCR1A = (int) ((float) topv * dutyCycle); //OCR1B = (int) ((float) topv * (1 - dutyCycle)); DDRB |= _BV(PORTB1) | _BV(PORTB2); TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(COM1A0) | _BV(COM1B0) ; sei(); } void setup() { //Serial.begin(9600); pinMode(9, OUTPUT); pinMode(10, OUTPUT); //pinMode (3, OUTPUT); DDRD |= B01000000; } byte a = 0; unsigned long t_start = 0; unsigned long t_peak = 0; unsigned long t = 0; byte v_peak = 0; const float SPEED_OF_SOUND_20C = 0.0003432; //per micro-second float d = 0; void loop() { startTransducer(1000000.0, 0.5); delayMicroseconds(8); stopTransducer(); delayMicroseconds(10); DDRD |= B00001000; PORTD &= ~(1 << PD3); //set PD3 low v_peak = 0; t_start = micros(); t_peak = t_start; for (int i = 0; i < 256; i++) { a = analogRead(0); t = micros(); if (a > v_peak) { t_peak = t; v_peak = a; } } t = t_peak - t_start; d = (float) t * SPEED_OF_SOUND_20C / 2.0; //Serial.println(d , 2); PORTD |= 1 << PD3; DDRD &= B00000000; delay(100); }
This is the result of the code from the oscilloscope:
My Challenge
How to twist the code above to generate a signal as in figure 1 with Atmega328P (Arduino). I have a little knowledge about timers for AVR, I will appreciate any help from the community. Thank you.