I want to use Arduino-mega generate multiple square wave signal,the siganl is 40kHz and it can be used to drive ultrasonic transducer.
So,I use the trategy in article "Ultraino: An Open Phased-Array System for
Narrowband Airborne Ultrasound Transmission",which apply 10 bit signal with sequence of '0' or '1' in PORTA,PORTC...etc to get a square wave signal like Fig 1.
Fig.1 square wave signal
Then I change the sequence pattern to shift phase,and just only 10 phases,some problem happen.
I am curious about the principle of this method:
-
Why the sequence can generate signal with 40kHz?Does it mean Arduino will cost serval microseconds executing command like
POTRA=0x1
. I try to change the length of the array,it will no longer generate the square wave well. -
When I execute the shift function
shiftPhase
,it have 10 phase.In 5 phase it will move the square wave like Fig.2,the other 5 phase will be like Fig3,the duty of square wave is changed,just like inverted.So,how does it happen,just with change the sequence of 0,1?
the code I use is:
#include <avr/sleep.h>
#include <avr/power.h>
#define N_PATTERNS 1
#define N_PORTS 10
#define N_DIVS 10
#define COMMAND_SWITCH 0b00000000
#define COMMAND_DURATION 0b00110000
#define MASK_DURATION 0b00111111
#define COMMAND_COMMITDURATIONS 0b00010000
#define WAIT(a) __asm__ __volatile__ ("nop")
#define OUTPUT_WAVE(pointer, d) PORTA = pointer[d*N_PORTS + 0]; PORTC = pointer[d*N_PORTS + 1]; PORTL = pointer[d*N_PORTS + 2]; PORTB = pointer[d*N_PORTS + 3]; PORTK = pointer[d*N_PORTS + 4]; PORTF = pointer[d*N_PORTS + 5]; PORTH = pointer[d*N_PORTS + 6]; PORTD = pointer[d*N_PORTS + 7]; PORTG = pointer[d*N_PORTS + 8]; PORTJ = pointer[d*N_PORTS + 9]
static byte bufferA[N_PATTERNS * N_DIVS * N_PORTS];
static byte bufferB[N_PATTERNS * N_DIVS * N_PORTS];
static byte animation[100] = {
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0xff,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
};
String str="";
void shiftPhase(byte* p,int len,int inter,int stepsize,byte id)
{
byte mask=0xff-id;
byte q[10]={0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};
for(int i=0;i<10;i++)
{
q[i]=p[i*inter];
}
for(int i=0;i<10;i++)
{
p[i*inter]=(q[(i+stepsize+10)%10]&id)|(mask&q[i]);
}
}
void setup()
{
//set as output ports A C L B K F H D G J
DDRA = DDRC = DDRL = DDRB = DDRK = DDRF = DDRH = DDRD = DDRG = DDRJ = 0xFF;
//low signal on all of them
PORTA = PORTC = PORTL = PORTB = PORTK = PORTF = PORTH = PORTD = PORTG = PORTJ = 0x00;
//clear the buffers
for (int i = 0; i < (N_PATTERNS * N_DIVS * N_PORTS); ++i) {
bufferA[i] = bufferB[i] = 0;
}
for (int i = 0; i < 100; ++i)
{
bufferA[i] = animation[i];
}
// disable everything that we do not need
ADCSRA = 0; // ADC
power_adc_disable ();
power_spi_disable();
power_twi_disable();
power_timer0_disable();
power_usart1_disable();
power_usart2_disable();
Serial.begin(9600);
byte bReceived = 0;
bool byteReady = false;
bool emittingA = true;
byte* emittingPointerH = & bufferA[0];
byte* emittingPointerL = & bufferA[N_PORTS * N_DIVS / 2];
LOOP:
OUTPUT_WAVE(emittingPointerH, 0);
OUTPUT_WAVE(emittingPointerH, 1);
OUTPUT_WAVE(emittingPointerH, 2);
OUTPUT_WAVE(emittingPointerH, 3);
OUTPUT_WAVE(emittingPointerH, 4);
OUTPUT_WAVE(emittingPointerL, 0);
OUTPUT_WAVE(emittingPointerL, 1);
OUTPUT_WAVE(emittingPointerL, 2);
OUTPUT_WAVE(emittingPointerL, 3);
OUTPUT_WAVE(emittingPointerL, 4);
byteReady = Serial.available();
if(byteReady!=0)
{
str="";
str=char(Serial.read());
Serial.println(str);
if(str=="1")
{
shiftPhase(bufferA,10,10,1,0x1);
}
if(str=="2")
{
shiftPhase(bufferA,10,10,-1,0x1);
}
}
while(Serial.read()>=0){}
goto LOOP;
}
void loop() {}
Thanks a lot!
The code of the article can be see in link.