This shows you the differences between two versions of the page.
pm:lab:lab4-2021 [2021/04/05 09:48] jan.vaduva |
pm:lab:lab4-2021 [2021/04/05 12:15] (current) alexandru.predescu [4. Exercitii] |
||
---|---|---|---|
Line 119: | Line 119: | ||
**Task 0** Folositi cod Arduino pentru a citi valoarea unui potentiometru si a unui senzor de temperatura si apoi trimiteti valorile pe seriala. | **Task 0** Folositi cod Arduino pentru a citi valoarea unui potentiometru si a unui senzor de temperatura si apoi trimiteti valorile pe seriala. | ||
- Valoarea potentiometrului ar trebui transmisa catre consola ca un procent. Va trebui sa convertiti numarul citit de ADC la un procent intre 0% si 100%. | - Valoarea potentiometrului ar trebui transmisa catre consola ca un procent. Va trebui sa convertiti numarul citit de ADC la un procent intre 0% si 100%. | ||
- | - Valoarea citita pentru senzorul de temperatura trebuie sa fie exprimata in grade celsius. Tensiunea de iesire a senzorului variaza liniar cu temperatura. Puteti sa faceti conversia experimental sau folosindu-va de datasheet (TMP36 - link-ul este mai jos). | + | - Valoarea citita pentru senzorul de temperatura trebuie sa fie exprimata in grade Celsius. Tensiunea de iesire a senzorului variaza liniar cu temperatura. Puteti sa faceti conversia experimental sau folosindu-va de datasheet ([[https://www.analog.com/media/en/technical-documentation/data-sheets/TMP35_36_37.pdf|Datasheet TMP36 ]]). |
{{ pm:lab:PB1.png?500 | PB1 }} | {{ pm:lab:PB1.png?500 | PB1 }} | ||
- | **Task 1** Folosind cod specific de microcontroller, cititi valoarea potentiometrului doar atunci cand se apasa un buton. (Codul trebuie testat pe Ardunino, Tinkercad nu are suport pentru Auto-trigger). | + | <hidden> |
+ | **Soluția** se găsește pe [[https://www.tinkercad.com/things/b2Yra0sAu2J-brilliant-lappi-habbi/editel?sharecode=LfeWdU6ojyT1VzyOCdjwU3ieYR6u4bV2-lEko5iVrTc|Tinkercad TMP36]] | ||
+ | </hidden> | ||
+ | |||
+ | **Task 1** Folosind cod specific de microcontroller, cititi valoarea potentiometrului doar atunci cand se apasa un buton. | ||
+ | <note>Codul trebuie testat pe Arduino, Tinkercad nu are suport pentru Auto-trigger.</note> | ||
{{ pm:lab:PB2.png?500 | PB2 }} | {{ pm:lab:PB2.png?500 | PB2 }} | ||
+ | <hidden> | ||
+ | **Soluția** se găsește pe [[https://www.tinkercad.com/things/b2Yra0sAu2J-brilliant-lappi-habbi/editel?sharecode=LfeWdU6ojyT1VzyOCdjwU3ieYR6u4bV2-lEko5iVrTc|Tinkercad Interrupt]] | ||
+ | |||
+ | <code> | ||
+ | void timer_setup(){ | ||
+ | // set timer A for 10ms | ||
+ | TCCR0A = 0; | ||
+ | TCCR0B = 0; | ||
+ | TCNT0 = 0; | ||
+ | |||
+ | OCR0A = 156; // compare match -> 10ms | ||
+ | TCCR0A |= (1 << WGM01); // CTC mode | ||
+ | TCCR0B |= ((1 << CS02) | (1 << CS00)); // 1024 prescaler | ||
+ | TIMSK0 |= (1 << OCIE0A); | ||
+ | |||
+ | // Enable timer as source | ||
+ | ADCSRB |= ((1 << ADTS0) | (1 << ADTS1)); | ||
+ | } | ||
+ | |||
+ | void button_setup(){ | ||
+ | // Select INT0 as trigger source | ||
+ | ADCSRB = 0; | ||
+ | ADCSRB |= (1 << ADTS1); | ||
+ | |||
+ | // Enable INT0 | ||
+ | EICRA |= (1 << ISC00); | ||
+ | EIMSK |= (1 << INT0); | ||
+ | } | ||
+ | |||
+ | |||
+ | void setup() | ||
+ | { | ||
+ | | ||
+ | // disable interrupts | ||
+ | cli(); | ||
+ | | ||
+ | ADMUX = 0; | ||
+ | /* AVCC with external capacitor at AREF pin */ | ||
+ | ADMUX |= (1 << REFS0); | ||
+ | |||
+ | ADCSRA = 0; | ||
+ | /* set prescaler at 128 */ | ||
+ | ADCSRA |= (7 << ADPS0); | ||
+ | |||
+ | // Enable auto-trigger | ||
+ | ADCSRA |= (1 << ADATE); | ||
+ | // Enable Intrerupt | ||
+ | ADCSRA |= (1 << ADIE); | ||
+ | |||
+ | // Set button as trigger source | ||
+ | button_setup(); | ||
+ | |||
+ | // Select Timer as trigger source | ||
+ | //timer_setup(); | ||
+ | | ||
+ | /* enable ADC */ | ||
+ | ADCSRA |= (1 << ADEN); | ||
+ | |||
+ | // Enable interrupts | ||
+ | sei(); | ||
+ | Serial.begin(9600); | ||
+ | } | ||
+ | |||
+ | ISR(ADC_vect){ | ||
+ | Serial.println(ADC); | ||
+ | } | ||
+ | |||
+ | ISR(INT0_vect) | ||
+ | { | ||
+ | Serial.println("Button Pressed!"); | ||
+ | } | ||
+ | |||
+ | ISR(TIMER0_COMPA_vect){ | ||
+ | // Even if this does nothing. It has to be here | ||
+ | // Else the code just doesn't work. Still don't know why. | ||
+ | // [AP] Deoarece ai activat intreruperea de compare match: TIMSK0 |= (1 << OCIE0A); | ||
+ | // [AP] Astfel, daca nu e definit ISR-ul se va reseta uC | ||
+ | } | ||
+ | |||
+ | void loop() | ||
+ | { | ||
+ | delay(50); | ||
+ | } | ||
+ | </code> | ||
+ | </hidden> | ||
+ | |||
+ | **Task 2** Folosind cod specific microcontrollerului cititi valoarea potentiometrului o data la 10ms. Pentru aceste exercitiu trebuie sa folositi ADC-ul sa porneasca o conversie automat in functie de un timer. | ||
+ | <note>Codul trebuie testat pe Arduino, Tinkercad nu are suport pentru Auto-trigger.</note> | ||
+ | |||
+ | <hidden> | ||
+ | **Soluția** se găsește pe [[https://www.tinkercad.com/things/grYhoajb3sd-exquisite-hango-waasa/editel?sharecode=gNPGmOuI6oZBx3bp-q-S7NlxWoz_wRwWZm9LJK4DHbI|Tinkercad Potentiometer]] | ||
+ | |||
+ | <code> | ||
+ | void timer_setup(){ | ||
+ | // set timer A for 10ms | ||
+ | TCCR0A = 0; | ||
+ | TCCR0B = 0; | ||
+ | TCNT0 = 0; | ||
+ | |||
+ | OCR0A = 156; // compare match -> 10ms | ||
+ | TCCR0A |= (1 << WGM01); // CTC mode | ||
+ | TCCR0B |= ((1 << CS02) | (1 << CS00)); // 1024 prescaler | ||
+ | TIMSK0 |= (1 << OCIE0A); | ||
+ | |||
+ | // Enable timer as source | ||
+ | ADCSRB |= ((1 << ADTS0) | (1 << ADTS1)); | ||
+ | } | ||
+ | |||
+ | void setup() | ||
+ | { | ||
+ | pinMode(2, INPUT_PULLUP); | ||
+ | | ||
+ | // disable interrupts | ||
+ | cli(); | ||
+ | | ||
+ | ADMUX = 0; | ||
+ | /* AVCC with external capacitor at AREF pin */ | ||
+ | ADMUX |= (1 << REFS0); | ||
+ | |||
+ | ADCSRA = 0; | ||
+ | /* set prescaler at 128 */ | ||
+ | ADCSRA |= (7 << ADPS0); | ||
+ | |||
+ | // Enable auto-trigger | ||
+ | ADCSRA |= (1 << ADATE); | ||
+ | // Enable Intrerupt | ||
+ | ADCSRA |= (1 << ADIE); | ||
+ | | ||
+ | // Select Timer as trigger source | ||
+ | timer_setup(); | ||
+ | | ||
+ | /* enable ADC */ | ||
+ | ADCSRA |= (1 << ADEN); | ||
+ | |||
+ | // Enable interrupts | ||
+ | sei(); | ||
+ | Serial.begin(9600); | ||
+ | } | ||
+ | |||
+ | ISR(ADC_vect){ | ||
+ | Serial.println(ADC); | ||
+ | } | ||
+ | |||
+ | ISR(TIMER0_COMPA_vect){ | ||
+ | // Even if this does nothing. It has to be here | ||
+ | // Else the code just doesn't work. Still don't know why. | ||
+ | // [AP] Deoarece ai activat intreruperea de compare match: TIMSK0 |= (1 << OCIE0A); | ||
+ | // [AP] Astfel, daca nu e definit ISR-ul se va reseta uC | ||
+ | } | ||
- | **Task 2** Folosind cod specific microcontrollerului cititi valoarea potentiometrului o data la 10ms. Pentru aceste exercitiu trebuie sa folositi ADC-ul sa porneasca o conversie automat in functie de un timer. (Codul trebuie testat pe Ardunino, Tinkercad nu are suport pentru Auto-trigger). | + | void loop() |
+ | { | ||
+ | delay(50); | ||
+ | } | ||
+ | </code> | ||
+ | </hidden> | ||
===== 5. Resurse ===== | ===== 5. Resurse ===== | ||
Line 136: | Line 295: | ||
===== 6. Linkuri Utile ===== | ===== 6. Linkuri Utile ===== | ||
* [[https://www.arduino.cc/reference/en/language/functions/analog-io/analogread/|Arduino Analog Read]] | * [[https://www.arduino.cc/reference/en/language/functions/analog-io/analogread/|Arduino Analog Read]] | ||
- | * [[https://www.analog.com/media/en/technical-documentation/data-sheets/TMP35_36_37.pd|Datasheet TMP36 ]] | + | * [[https://www.analog.com/media/en/technical-documentation/data-sheets/TMP35_36_37.pdf|Datasheet TMP36 ]] |
- | * [[https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pd|Datasheet ATmega328p]] | + | * [[https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf|Datasheet ATmega328p]] |