• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Jak uzyskać fale sinusoidalną w Arduino UNO ?

Object Storage Arubacloud
0 głosów
281 wizyt
pytanie zadane 23 sierpnia 2018 w Mikrokontrolery przez niezalogowany
Witam, robię projekt "automatycznego" nadajnika morse'a opis działania programu:

1.Odbierz litery i cyfry z portu komunikacyjnego
2.Na pinie 9 wygeneruj ton(~1000hz) z przerwami odpowiadający literze bądź cyfrze

I własnie z tym generowaniem tonu jest problem, bo Arduino generuje falę tzw. kwadratową, a mi jest potrzebna sinusoidalna ponieważ taką się nadaje używając morse'a.

Z góry dziękuję.
Pozdrawiam Michał

PS: Jestem początkujący w Arduino, a w generowaniu tonów to już wogóle.

2 odpowiedzi

0 głosów
odpowiedź 23 sierpnia 2018 przez Bondrusiek Maniak (61,370 p.)

Witam,

z tego co wiem to Arduino nie może wygenerować fali sinusoidalnej. Musisz użyć przybliżenia

Tu masz przykład czysto teoretyczny : https://www.tek.com/blog/tutorial-digital-analog-conversion-r-2r-dac

Przykładowy kod znaleziony w necie


// PIN 13 will have a 2.5 Hz square wave on it.
// PIN 3 will have a PWM signal on it, with a duty cycle that keeps changing in time. The mathematical 'time-average' of the PWM signal's amplitude will be proportional to the instantaneous amplitude of a DC-offsetted sinewave.

// NOTE that the frequency in this example is very low. The interrupt frequency is only 10 Hz, which means an interrupt every 0.1 second. If we have 256 values for our DC-offsetted sinewave (from the wave-table), then each 'amplitude' voltage will be generated with 1 second gaps, which means it would take a long time (such as 25.5 seconds) for a full cycle of the amplitude values.
//

boolean toggle1 = 0;

int pwmPin_timer1 = 3;

volatile int indexer = 0;


unsigned char sinewave[] =                // Preset 256 values of a binary conversions of a sine wave having a POSITIVE DC OFFSET. It represents sinewave with a positive DC offet. This is done because the arduino doesn't handle NEGATIVE voltages.
{
0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x02,0x02,0x03,0x04,0x05,0x06,0x06,0x07,0x09,
0x0a,0x0b,0x0c,0x0e,0x0f,0x11,0x12,0x14,0x16,0x17,0x19,0x1b,0x1d,0x1f,0x21,0x23,
0x25,0x28,0x2a,0x2c,0x2f,0x31,0x34,0x36,0x39,0x3c,0x3e,0x41,0x44,0x46,0x49,0x4c,
0x4f,0x52,0x55,0x58,0x5b,0x5e,0x61,0x64,0x67,0x6a,0x6d,0x70,0x73,0x77,0x7a,0x7d,
0x80,0x83,0x86,0x89,0x8d,0x90,0x93,0x96,0x99,0x9c,0x9f,0xa2,0xa5,0xa8,0xab,0xae,
0xb1,0xb4,0xb7,0xba,0xbc,0xbf,0xc2,0xc4,0xc7,0xca,0xcc,0xcf,0xd1,0xd4,0xd6,0xd8,
0xdb,0xdd,0xdf,0xe1,0xe3,0xe5,0xe7,0xe9,0xea,0xec,0xee,0xef,0xf1,0xf2,0xf4,0xf5,
0xf6,0xf7,0xf9,0xfa,0xfa,0xfb,0xfc,0xfd,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfd,0xfc,0xfb,0xfa,0xfa,0xf9,0xf7,
0xf6,0xf5,0xf4,0xf2,0xf1,0xef,0xee,0xec,0xea,0xe9,0xe7,0xe5,0xe3,0xe1,0xdf,0xdd,
0xdb,0xd8,0xd6,0xd4,0xd1,0xcf,0xcc,0xca,0xc7,0xc4,0xc2,0xbf,0xbc,0xba,0xb7,0xb4,
0xb1,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x99,0x96,0x93,0x90,0x8d,0x89,0x86,0x83,
0x80,0x7d,0x7a,0x77,0x73,0x70,0x6d,0x6a,0x67,0x64,0x61,0x5e,0x5b,0x58,0x55,0x52,
0x4f,0x4c,0x49,0x46,0x44,0x41,0x3e,0x3c,0x39,0x36,0x34,0x31,0x2f,0x2c,0x2a,0x28,
0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,0x16,0x14,0x12,0x11,0x0f,0x0e,0x0c,0x0b,
0x0a,0x09,0x07,0x06,0x06,0x05,0x04,0x03,0x02,0x02,0x01,0x01,0x01,0x00,0x00,0x00
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup(){
  Serial.begin(9600);
  pinMode(pwmPin_timer1, OUTPUT); //configured a valid pin for PWM output

cli();//stop interrupts
  

//NOTE: registers TCCR1A, TCCR1B, TCNT1, OCR1A etc. are PREDEFINED within a header file. They are registers related the setup of the arduino timers.
  TCCR1A = 0;// initialise to zero.
  TCCR1B = 0;// same for TCCR1B
  TCNT1  = 0;//initialise counter value to 0
  
  OCR1A = 1563;   // timer compare value;   = [(16*10^6) / (10*1024)] - 1 (must be <65536) = MAXCOUNT = [(raw timer clock frequency) / (desired_interrupt_freq * prescale_divisor)] - 1, which comes from formula: prescaled_clockperiod = 1/prescaled_clockfreq; desired_interrupt_period = 1/10 = n.prescaled_clockperiod; maxcount = N = OCR0A = n-1; n is new divisor; prescaled_clockperiod = 1/(16MHz/prescale_divisor); a prescale_divisor of 1024 is set by CS10, CS11, CS12 of TCCR1B register.
  TCCR1A |= 0;
    
  // set up timer with prescaler = 1 and turn on CTC mode; CS10 CS11 and CS12 are bit0, bit1, and bit2 of the TCC1B register, respectively. Example prescaler options: Making CS11=1 and CS10=1 yields divide by 64. Making CS12=1 and CS11=1 yields divide by 1024. Refer to timer1 prescale table in a user manual for other combinations.
  //TCCR1B |= (1 << WGM12)|(1 << CS11)|(1 << CS10);     //use this for divide by 64 (ie. 'prescaler 64')
  TCCR1B |= (1 << WGM12)|(1 << CS12)|(1 << CS10);     //use this for divide by 1024
  //TCCR1B |= (1 << WGM12)|(1 << CS11);     //use this for divide by 8
  //TCCR1B |= (1 << WGM12)|(1 << CS10);     //use this for divide by 1  


  // turn on CTC mode
  //TCCR1B |= (1 << WGM12); //WGM12 is bit3 of the TCCR1B register (4th bit from the right). This turns on CTC mode (timer mode 4)

  //Timer1 has 2 separate control registers. Each one contains bits for setting up features associated with timer1. Some bits, like the set of Waveform Generation WG bits are scattered so that some of the bits are in one register, while the other bits are in the second register.
  
  // enable timer compare interrupt
  TIMSK1 |= (1 << OCIE1A);

  sei();//allow interrupts

}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
void loop()
{
//put things here if needed
}


ISR(TIMER1_COMPA_vect){//timer1 interrupt with frequency of 10Hz will toggle pin 13 (LED)
  //this service routine generates pulse wave of frequency 10Hz/2 = 2.5Hz (takes two cycles for full wave- toggle high then toggle low) at digital pin 13
  //analogWrite(pwmPin_timer1,128);  //setPwmDuty(pwmPin_timer1, dutycycle)
  
  //also generates PWM encoded DC-offsetted sinewave at digital pin 3
  //write some code here .....

// pin 3, sinewave (plus positive DC offset) instantaneous amplitude encoded as PWM signals. The mathematical time-average of the constantly changing PWM signal will be the instantaneous amplitude of the encoded sine-wave. Therefore, it will be necessary to low-pass filter the PWM signal in order to 'observe' the encoded sine-wave.
  analogWrite(pwmPin_timer1, sinewave[indexer]);
  indexer++;
  if (indexer == 256) {
  indexer = 0;
  }

// pin 13, square-wave signal;  note that the frequency of the squarewave will be half of the interrupt frequency, due to the toggling. So if the interrupt frequency is 10 Hz, then the square wave's frequency will be 2.5 Hertz.
  if (toggle1){
    digitalWrite(13,HIGH);
    toggle1 = 0;
  }
  else{
    digitalWrite(13,LOW);
    toggle1 = 1;
  }
  
}

Za (https://forum.arduino.cc/index.php?topic=446209.4). W tym temacie jest poruszany przez Ciebie problem.

komentarz 23 sierpnia 2018 przez niezalogowany
Dziękuję za odpowiedź jakoś o 16 dopiero przetestuje bo aktualnie nie jestem w domu.
0 głosów
odpowiedź 23 sierpnia 2018 przez izonik Stary wyjadacz (12,560 p.)
Może uda ci się wykorzystać bibliotekę Mozzi https://sensorium.github.io/Mozzi/ . Ale to może, nigdy nie generowałem fal w arduino.

Pozdrawiam.
komentarz 23 sierpnia 2018 przez niezalogowany
Dziękuję za odpowiedź jakoś o 16 dopiero przetestuje bo aktualnie nie jestem w domu.

Podobne pytania

0 głosów
0 odpowiedzi 183 wizyt
0 głosów
0 odpowiedzi 451 wizyt
0 głosów
1 odpowiedź 169 wizyt
pytanie zadane 17 grudnia 2016 w Mikrokontrolery przez Aragedens Obywatel (1,120 p.)

92,576 zapytań

141,426 odpowiedzi

319,651 komentarzy

61,961 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...