Ovládanie RGB LED cez Processing
Zo stránky SensorWiki
Záverečný projekt predmetu MIPS / LS2024 - Šimon Vretenička
Zadanie
Naprogramujte RGB LED v prostredí AVR Studio na vývojovej doske a ovladanú pomocou softvéru Processing.org

Literatúra:
Analýza a opis riešenia
Úloha bola inšpirovaná z cvičenia 7, v ktorom sme pomocou plnenia používali Led diódu. V tomto prípade sme používali RGB diódu OSTAMA51A5A.
Postupovali sme nasledovne:
1. ZAPOJENIE Podľa datacheetu Ledky OSTAMA51A5A sme si naštudovali schému a princíp zapojenia nožičiek diódy a následne zapojili do obvodu.

Schéma zapojenia: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2. AVR Studio Kód, ktorý umožňuje riadiť RGB LED pomocou hodnôt posielaných z Processing aplikácie cez sériovú komunikáciu (UART).
- Zadefinovanie pinov
 
Červená (Red): PB3 (OCR2A) Zelená (Green): PB1 (OCR1A) Modrá (Blue): PB2 (OCR1B)
- Definícia frekvencie CPU:
 
Definujeme frekvenciu mikrokontroléra na 16 MHz. Táto hodnota sa používa pri výpočtoch času a predeľov v časovačoch.
#define F_CPU 16000000UL
- Časovače:
 
Pomocou funkcie setup_timers() inicializujeme časovače Timer1 a Timer2 pre PWM (Pulse Width Modulation).
Timer1 je nastavený pre PWM na pinoch PB1 (OC1A) a PB2 (OC1B). Jeho top hodnota (ICR1) je nastavená na 255, čo umožňuje 8-bitový PWM. Timer2 je nastavený pre PWM na pine PB3 (OC2A).
- Komunikácia cez UART:
 
Pomocou funkcie setup_uart() inicializujeme sériovú komunikáciu (UART) na rýchlosť 9600 baud. Následne sa vypočíta hodnota UBRR (UART Baud Rate Register) na základe frekvencie CPU a požadovanej baudovej rýchlosti.
- Vysielanie a prijímanie pomocou UART:
 
Pomocou funkcie uart_transmit() budeme odosielať jeden bajt cez UART. Pracuje na princípe, že čaká, kým nie je UART Data Register prázdny, a potom pošle údaje. Taktiež pomocou funkcie uart_receive() budeme prijímať jeden bajt cez UART. Táto funkcia čaká, kým nie je pripravený nový bajt v UART Data Register, a potom ho vráti.
- Nastavenie výstupných pinov:
 
Nastavujeme piny PB1, PB2 a PB3 ako výstupné. Tieto piny budú použité na ovládanie RGB LED.
- Povolenie globálnych prerušení:
 
Na toto použijeme funkciu sei(), tá povolí globálne prerušenia, čo nám umožní obsluhu prerušení.
- Slučka WHILE:
 
Kód v tejto slučke sa neustále opakuje. V každom oparkovaní sa prijme hodnota pre červenú, zelenú a modrú z Processing aplikácie cez UART. Hodnoty sa inverzne upravia (255 - hodnota), pretože farba 255 znamená maximálnu intenzitu a 0 znamená žiadnu intenzitu.
   Tieto hodnoty sa potom priradia k PWM registrom pre každú farbu:
       OCR2A = red; nastavuje PWM pre červenú LED na PB3.
       OCR1B = blue; nastavuje PWM pre modrú LED na PB2.
       OCR1A = green; nastavuje PWM pre zelenú LED na PB1.
3. Processing Kód v softvéri musí byť v jazyku Java, keďže s týmto jazykom nemám žiadne skúsenosti musel som si naštudovať ako to v tom programe funguje (a ako sa prepojí pomocou sériovej linky na Arduino.) a taktiež som si pomohol rôznymi inými vzorovými kódmi, ktoré som prispôsobil pre môj program.
Postup kódu:
- Deklarácia premenných
 
Serial myPort; a ControlP5 cp5; deklarujú premenné pre sériovú komunikáciu a ControlP5 GUI ovládanie. int redValue = 0;, int greenValue = 0;, int blueValue = 0; inicializujú premenné pre hodnoty červenej, zelenej a modrej farby.
- Funkcia setup():
 
size(350, 480); nastavuje veľkosť okna.
cp5 = new ControlP5(this); inicializuje ControlP5 knižnicu pre GUI ovládanie.
cp5.addSlider("redValue")... pridáva slider pre červenú farbu, nastavuje jeho polohu, veľkosť a rozsah hodnôt.
Obdobne sa pridávajú slidre pre zelenú a modrú farbu.
myPort = new Serial(this, "COM7", 9600); inicializuje sériovú komunikáciu na daný sériový port a rýchlosť.
- Funkcia draw():
 
background(255); vyčistí plátno a nastaví bielu farbu pozadia.
fill(redValue, greenValue, blueValue); nastavuje farbu vyplnenia podľa aktuálnych hodnôt farieb.
rect(20, 250, 300, 200); kreslí obdĺžnik na základe aktuálnych hodnôt farieb.
fill(0); nastavuje farbu textu na čiernu.
text("Red: " + redValue, 20, 40); a podobné riadky vypisujú hodnoty farieb na plátno.
myPort.write(redValue);, myPort.write(greenValue);, myPort.write(blueValue); posielajú hodnoty farieb cez sériovú komunikáciu na Arduino.
- Funkcia controlEvent():
 
Táto funkcia spracováva udalosti ovládačov GUI. Ak bola zmenená hodnota červenej farby, aktualizuje sa premenná redValue. Takisto pre zelenú a modrú farbu.
Nezabudnite doplniť schému zapojenia!
Algoritmus a program
Algoritmus programu pre AVR Studio je....
#define F_CPU 16000000UL  // Definícia frekvencie CPU 16 MHz
#include <avr/io.h>
#include <avr/interrupt.h>
void setup_timers() {
    // Nastavenie Timer1 pre PWM na PB1 (OC1A) a PB2 (OC1B)
    TCCR1A |= (1 << COM1A1) | (1 << COM1B1) | (1 << WGM11);
    TCCR1B |= (1 << WGM12) | (1 << WGM13) | (1 << CS10);
    ICR1 = 255;  // Top hodnota pre 8-bitové PWM
    // Nastavenie Timer2 pre PWM na PB3 (OC2A)
    TCCR2A |= (1 << COM2A1) | (1 << WGM20) | (1 << WGM21);
    TCCR2B |= (1 << CS20);
}
void setup_uart() {
    // Nastavenie UART na 9600 baud
    uint16_t ubrr = F_CPU/16/9600-1;
    UBRR0H = (ubrr >> 8);
    UBRR0L = ubrr;
    UCSR0B |= (1 << RXEN0) | (1 << TXEN0);  // Povoliť Rx a Tx
    UCSR0C |= (1 << UCSZ01) | (1 << UCSZ00); // 8-bitové dáta
}
void uart_transmit(uint8_t data) {
    while (!(UCSR0A & (1 << UDRE0)));
    UDR0 = data;
}
uint8_t uart_receive() {
    while (!(UCSR0A & (1 << RXC0)));
    return UDR0;
}
int main(void) {
    setup_timers();
    setup_uart();
    DDRB |= (1 << PB1) | (1 << PB2) | (1 << PB3);  // Nastavenie pinov PB1, PB2 a PB3 ako výstup
    sei();  // Povoliť globálne prerušenia
    while (1) {
        uint8_t red = 255 - uart_receive();
        uint8_t green = 255 - uart_receive();
        uint8_t blue = 255 - uart_receive();
        OCR2A = red;    // Nastavenie PWM pre červenú LED na PB3
        OCR1B = blue;   // Nastavenie PWM pre modrú LED na PB2
        OCR1A = green;  // Nastavenie PWM pre zelenú LED na PB1
    }
}
import processing.serial.*;
import controlP5.*;
Serial myPort;
ControlP5 cp5;
int redValue = 0;
int greenValue = 0;
int blueValue = 0;
void setup() {
  size(350, 480);
  cp5 = new ControlP5(this);
  
  cp5.addSlider("redValue")
     .setPosition(20, 50)
     .setSize(300, 40)  // Nastavenie veľkosti slidra
     .setRange(0, 255)
     .setValue(redValue);
  
  cp5.addSlider("greenValue")
     .setPosition(20, 120)  // Posunutie slidra nižšie
     .setSize(300, 40)  // Nastavenie veľkosti slidra
     .setRange(0, 255)
     .setValue(greenValue);
  
  cp5.addSlider("blueValue")
     .setPosition(20, 190)  // Posunutie slidra nižšie
     .setSize(300, 40)  // Nastavenie veľkosti slidra
     .setRange(0, 255)
     .setValue(blueValue);
  myPort = new Serial(this, "COM7", 9600);  // Nastav správny port
}
void draw() {
  background(255);
  
  fill(redValue, greenValue, blueValue);
  rect(20, 250, 300, 200);
  
  fill(0);
  text("Red: " + redValue, 20, 40);
  text("Green: " + greenValue, 20, 110);
  text("Blue: " + blueValue, 20, 180);
  
  // Posielanie hodnôt do Arduina
  myPort.write(redValue);
  myPort.write(greenValue);
  myPort.write(blueValue);
}
void controlEvent(ControlEvent theEvent) {
  if (theEvent.isFrom("redValue")) {
    redValue = int(theEvent.getValue());
  }
  if (theEvent.isFrom("greenValue")) {
    greenValue = int(theEvent.getValue());
  }
  if (theEvent.isFrom("blueValue")) {
    blueValue = int(theEvent.getValue());
  }
}
Pridajte sem aj zbalený kompletný projekt, napríklad takto (použite jednoznačné pomenovanie, nemôžeme mať na serveri 10x zdrojaky.zip:
Zdrojový kód: zdrojaky.zip
Overenie
Na používanie našej aplikácie stačia dve tlačítka a postup používania je opísaný v sekcii popis riešenia. Na konci uvádzame fotku záverečnej obrazovky pred resetom. Vypísaný je tu priemerný čas a najlepší čas.

Video:
Kľúčové slová 'Category', ktoré sú na konci stránky nemeňte.