Kosketusnäyttö (resistiivinen) + rgb led

Luin tuon mahtavan artikkelin resistiivisestä kosketusnäytöstä ja jutun lopussa oli, että Lauri on tehnyt kosketusnäytön, jolla voi ohjata rgb ledien värejä. Tuon saman idean Lauri tuossa aiemmassa aiheessa mainitsi (viewtopic.php?f=3&t=89) Itse en ole koskaan arduinolla mitään tehnyt, niin ajattelin, että tuollaisen kosketusnäyttö + rgb led yhdistelmän voisin tehdä. Tarkoitus olisi rakentaa itse tietokoneen kotelo ja laittaa sen sisälle rgb led valaistus, jonka värejä voi säätää kotelon seinästä olevasta kosketusnäytöstä. Tuossa myös yksi idea tuohon aiemmin mainitsemaani aiheeseen.
Elikkä mitä osia tarvitsen tuon rakentamiseen? Sen verran tiedän, että ainakin arduino duemilanove (voin varmaan korvata uudemmalla arduino uno:lla?), kosketusnäyttö ja rgb ledejä.
Arduino koodausta en ole koskaan kokeillut, enkä hirveästi muutakaan koodausta (hieman olen koodannut android puhelin käyttöjärjestelmälle), joten voisiko Lauri laittaa koodaamansa ohjelman (jolla siis ohjataan ledien värejä) julkiseen jakoon?
Miltäs kuulostaisi?

ruuvipenkki.fi/2010/11/02/re … tuspaneeli

Tämä projektihan siis vain tulostaa kosketuskohdan koordinaatit sarjaliikenteenä tietokoneelle, mutta värien säätöön tarvinnee hiukan lisää, koska rgb:ssä on kolme muuttujaa, ja nämä muuttujat pitäisi vielä muuttaa PWM:ksi rgb-ledille.

Arvaisin, että arvojen hakeminen tapahtuu siten, että x-akseli edustaa esim. sinistä, y punaista, ja vihreä tulisi niiden funktiona, esim. suora origosta (0,0) vastakkaiseen kulmaan.

eli me saadaan sieltä sense 0-1023 x 2

xval= AnalogRead 0;
yval= AnalogRead 1;
map xval (0, 1023, 0, 255); //tämä siis koska arduinon pwm on 0-255
map yval (0, 1023, 0, 255);
zval= (yval + xval / 2);

AnalogWrite  (3, xval);
AnalogWrite  (5, yval);
AnalogWrite  (6, zval);

Meniskö jotakuinkin näin? Täynnä virheitä varmaan, mutta en jaksanut kauheesti tarkistaa.
(ja täydellinen koodihan tuo ei ole…)

tosin, pitäisihän sen muistaakin edellinen arvo… eli jonkin sortin if lausetta kaivataan.

Ei se noin voi mennä.

Valkoinen RGB = FF FF FF
sinipunainen RGB = FF 00 FF

Jos kulmasta kulmaan akseli on vihreä niin sinipunaisen tekeminen on mahdotonta.

Olin ajatellut julkaista asiaan liittyvää koodiani myöhemmin artikkelin muodossa, mutta mitäpä sitä turhaan kaikelle kansalle tarkoitettua materiaalia pihtaamaan :smiley:

Alla olevasta koodista suurin osa on tehty kuukausia sitten (nyt pastetin uudet paneelinlukufunktiot jne siihen), joten en muista toimiko se täysin oikein ja kuinka nopeasti. Sen muistan, että jotain hyvääkin siinä oli :sunglasses:

Tutkikaa ja kommentoikaa.

[code]/****************************************************************************

  • Project: RGB Touch V0.1(Nintendo DS panel + Arduino Duemilanove + RGB LED)*
  • Author: Lauri Jämsä / http://www.ruuvipenkki.fi / lauri.jamsa@gmail.com *
  • Date: 03.11.2010 *
  • License: Attribution-NonCommercial-ShareAlike 1.0 Finland *
    ****************************************************************************/

#include “avr/interrupt.h”
#include “avr/io.h”

// Kosketuspaneelin johdotukset Arduino Duemilanoven pinneihin (jännitteet)
#define X_VCC 2
#define X_NC 3
#define X_GND 4
#define X_SENSE 5

#define Y_NC 2
#define Y_GND 3
#define Y_SENSE 4
#define Y_VCC 5

// Kosketuspaneelin johdotukset Arduino Duemilanoven ANALOG IN -pinneihin
#define SENSE_X 3
#define SENSE_Y 4

// RGB-ledin johdotukset Arduinolle (PWM-pinneille)
#define PIN_RED 9
#define PIN_GREEN 10
#define PIN_BLUE 11

// Hetkelliset AD-muuntimelta saadut arvot X- ja Y-koordinaateille
unsigned int X = 0;
unsigned int Y = 0;

// Duty cycle -arvot, joilla kirkastetaan ledejä (0 -> 255 = pois päältä -> kirkkain)
unsigned int redDuty = 0;
unsigned int greenDuty = 0;
unsigned int blueDuty = 0;

// Värikartan koko
unsigned int colorChartLeftX = 100;
unsigned int colorChartRightX = 730;
unsigned int colorChartTopY = 900;
unsigned int colorChartBottomY = 120;
unsigned int colorChartWidth = colorChartRightX - colorChartLeftX;
unsigned int colorChartHeight = colorChartTopY - colorChartBottomY;

// Ajetaan kertaalleen, kun Arduino käynnistetään
void setup()
{
Serial.begin(115200);

// Muutetaan timereiden 1 ja 2 prescaler-arvoja, jotta saadaan alennettua
// PWM:n taajuutta (kun prescaler = 256, taajuus 122,07Hz)
// (http://www.arduino.cc/playground/Main/TimerPWMCheatsheet)
// Lisäys: Parempi taajuus ledien PWM-ohjaukseen olisi >1000Hz, että
// liitoslämpötila pysyisi tasaisempana (lähdettä en muista)
TCCR1B = TCCR1B & 0b11111000 | 0x04; // Timer 1:n prescaler 256:ksi
TCCR2B = TCCR2B & 0b11111000 | 0x06; // Timer 2:n prescaler 256:ksi
}

// Funktio palauttaa toden, mikäli paneeliin kosketaan ja sijoittaa
// koordinaatit globaaleihin muuttujiin X ja Y:
boolean touch_panel() {
boolean touched = false; // Lähtötilanteessa aina false

// Vaakakoordinaatin (X) lukeminen:

pinMode(X_GND, OUTPUT); // X_GND ulostuloksi
digitalWrite(X_GND, LOW); // X_GND alas
pinMode(X_VCC, OUTPUT); // X_VCC ulostuloksi
digitalWrite(X_VCC, HIGH); // X_VCC ylös
pinMode(X_NC, INPUT); // X_NC korkeaimpedanssimoodiin
pinMode(X_SENSE, INPUT); // X_SENSE korkeaimpedanssimoodiin
delay(5); // Odotetaan 5ms ennen AD-muunnosta
X = analogRead(SENSE_X); // AD-muunnetaan

// Pystykoordinaatin (Y) lukeminen:

pinMode(Y_GND, OUTPUT); // Y_GND ulostuloksi
digitalWrite(Y_GND, LOW); // Y_GND alas
pinMode(Y_VCC, OUTPUT); // Y_VCC ulostuloksi
digitalWrite(Y_VCC, HIGH); // Y_VCC ylös
pinMode(Y_NC, INPUT); // Y_NC korkeaimpedanssimoodiin
pinMode(Y_SENSE, INPUT); // Y_SENSE korkeaimpedanssimoodiin
delay(5); // Odotetaan 5ms ennen AD-muunnosta
Y = analogRead(SENSE_Y); // AD-muunnetaan

// Huomioidaan painallukset ainoastaan, jos arvot ovat alle 1000:
// (0V = 0 ja 5V = 1023)
if((X < 1000) && (Y < 1000)) touched = true;

return touched;
}

void determineRedColor()
{
// Punaisen kova määritys
if ((((touchX <= (colorChartLeftX + (colorChartWidth/6))) ^
(touchX >= (colorChartRightX - (colorChartWidth/6))))) &&
(touchX <= colorChartRightX)) {
redDuty = 255;
}
// Jos 2. kuudenneksessa, eli punainen himmenee oikealle päin mentäessä
else if ((touchX > (colorChartLeftX + (colorChartWidth/6))) &&
(touchX < (colorChartLeftX + (colorChartWidth/3)))) {
redDuty = (colorChartWidth/6) - (touchX - (colorChartLeftX + (colorChartWidth/6)));
redDuty = scale(redDuty);
}
// Jos 5. kuudenneksessa, eli punainen kirkastuu oikealle päin mentäessä
else if ((touchX > (colorChartLeftX + (2 * (colorChartWidth/3)))) &&
(touchX < (colorChartRightX - (colorChartWidth/6)))) {
redDuty = (touchX - (colorChartLeftX + (2 * (colorChartWidth/3))));
redDuty = scale(redDuty);
}
// Muulloin tiedetään, että väri on nollilla
else redDuty = 0;
}

void determineGreenColor()
{
// Vihreän kova määritys
if ((touchX >= (colorChartLeftX + (colorChartWidth/6))) &&
(touchX <= (colorChartRightX - (colorChartWidth/2)))) {
greenDuty = 255;
}
// Jos 1. kuudenneksessa, eli vihreä kirkastuu oikealle päin mentäessä
else if ((touchX > (colorChartLeftX)) &&
(touchX < (colorChartLeftX + (colorChartWidth/6)))) {
greenDuty = (touchX - (colorChartLeftX));
greenDuty = scale(greenDuty);
}
// Jos 4. kuudenneksessa, eli vihreä himmenee oikealle päin mentäessä
else if ((touchX > (colorChartLeftX + (colorChartWidth/2))) &&
(touchX < (colorChartRightX - (colorChartWidth/3)))) {
greenDuty = (colorChartWidth/6) - (touchX - (colorChartLeftX + (colorChartWidth/2)));
greenDuty = scale(greenDuty);
}
else greenDuty = 0;
}

void determineBlueColor()
{
//Sinisen kova määritys
if ((touchX >= (colorChartLeftX + (colorChartWidth/2))) &&
(touchX <= (colorChartRightX - (colorChartWidth/6)))) {
blueDuty = 255;
}
// Jos 3. kuudenneksessa, eli sininen kirkastuu oikealle päin mentäessä
else if ((touchX > (colorChartLeftX + (colorChartWidth/3))) &&
(touchX < (colorChartRightX - (colorChartWidth/3)))) {
blueDuty = (touchX - (colorChartLeftX + (colorChartWidth/3)));
blueDuty = scale(blueDuty);
}
// Jos 6. kuudenneksessa, eli sininen himmenee oikealle päin mentäessä
else if ((touchX > (colorChartRightX - (colorChartWidth/6))) &&
(touchX < (colorChartRightX))) {
blueDuty = (colorChartWidth/6) - (touchX - (colorChartRightX - (colorChartWidth/6)));
blueDuty = scale(blueDuty);
}
else blueDuty = 0;
}

// Skaalataan (colorChartWidth/6) välille 0-255
unsigned int scale(unsigned int notScaledYet)
{
notScaledYet = notScaledYet * ((255 * 100) / (((10 * colorChartWidth) / 6)));
unsigned int scaled = notScaledYet / 10;
return scaled;
}

// Loop-funktioon jäädään pyörimään loputtomasti
void loop()
{
// Jos paneeliin kosketaan, mennään tänne
if (touch_panel()) {
Serial.print(“greenDuty=”);
Serial.print(greenDuty);
Serial.print(" X=");
Serial.print(touchX);
Serial.print(" Y=");
Serial.println(touchY);
// Tässä voisi tulostaa myös kaikkien muiden värien duty-cyclet

determineRedColor();
determineGreenColor();
determineBlueColor();

// Asetetaan uudet arvot käyttöön
analogWrite(PIN_RED, redDuty);
analogWrite(PIN_GREEN, greenDuty);
analogWrite(PIN_BLUE, blueDuty);

}
}[/code]

Koodihan tekee (muistaakseni) kosketuspaneelista siis tuollaisen HUE-värikartan:

Jossain koodissani oli lisäominaisuuksiakin (himmennyssäädintä, saturaatiota jne.). En vain nyt sitä löytänyt ja muistaakseni se toimi vähän liian hitaasti. Täytyisi optimoida joskus kun ehtii.

Tuosta komponenttien tarpeesta vielä. Eli riippuu täysin tarvitsemastasi valon kirkkaudesta. Itse käytin 3 watin RGB-lediä, jota ohjailin NPN-transistorien avulla. Mikäli tavalliset 5mm:n RGB-ledit riittävät, niin ATmega328P jaksanee puskea niille (ainakin yhdelle) juuri ja juuri tarpeeksi virtaa. Tällöin et tarvitsisi muuta elektroniikkaa. Ja Arduino Uno käy myös hyvin.

Aikoinaan tietokonekoteloitakin (liikaa) modailleena voin sanoa, että mikäli haluat valaistuksen näkyvän myös päivänvalossa, niin tarvitset ainakin yhden tuollaisen suuriteholedin kuin mitä itse käytin.

Niitä saa edullisesti ainakin täältä:
dealextreme.com/details.dx/sku.4530
(kannattaa lukea käyttäjien kommentteja ledistä)

Kiitoksia koodista!
Jos laitan 2 noita 3 W rgb ledejä koteloon, niin riittääkö se valaisemaan koko kotelon hyvin? vai pistetäänkö vielä 1 lisää? Millaisia npn transistoreja tarvitsen? Ja noille ledeille tarvitaan varmaan jonkin näköinen lisä virtalähde?
Voisitko myös laittaa jonkinlaisen kaavion/kuvan, että mihinkä kosketusnäyttö, ledit ja yms liitetään. En tosiaan ole ennen arduinolla mitään tehnyt, niin en oikein tiedä kytkennöistä mitään.

Tuossa päivänä yhtenä kokeilin josko olisin osannut. Enpä osannutkaan. Tuli tehtyä pätkä C koodia, joka olisi mapannut X-Y maailman kolmeen tähden muotoiseen komponenttiin (RGB) ja arvot olisivat tulleet pympyrästä.

Bonuksena olisi saanut neljä näppäintä. Esim päälle/pois enempi ja vähempi. Taustalle olisi sitten voinut tulostaa tuon kuvion.

Ajatuksena kaunis, mutta toteutus jäi puolitiehen kun ei nyt oikein osannut. Olisi se ollut hieno.

Tuohon aiempaan koodiini voisin lisätä, että sehän näyttää olevan ohjelmoitu aika huonosti. Mikäli kääntäjä ei optimoi noita jakolaskuja pois, se suorittuu erittäin hitaasti. Satoja kertoja sekunnissa tosin silti, joten mikäli MCU:lla ei ole muuta tehtävää, niin varmasti menee sellaisenaan vielä…

Täytyisi optimoida ne pois ja en tiedä miksi olen esim. laittanut nuo värikartan raja-arvot globaaleilla muuttujilla enkä vain määritellyt niitä. Noh, täytynee parannella, kunhan ehdin leikkiä RGB Touch -projektini kanssa seuraavan kerran. :unamused:

Voisiko joku nyt vähän auttaa ensikertalaista alkuun? Olisi kiva, jos Lauri väsäisi artikkelin tuollaisen rgb led + kosketusnäyttö valmistuksesta. :slight_smile:

Artikkeli tulee kyllä jossain vaiheessa, kun ehdin sen kirjoittamaan. Sinulla taitaa mennä kuitenkin joitakin viikkoja, että saat tarvittavat komponentit kasaan?

Tuo ledi, jota mainostin, on yhteisanodikytketty, eli värit syntyvät maadoittamalla sen eri katodeita. Eri väreillä on myös eri kynnysjännitteet, joten etuvastukset tulee mitoittaa sen mukaan. Ohjeen etuvastuksen mitoituksesta olenkin jo kirjoittanut:

ruuvipenkki.fi/2010/08/05/le … n-mitoitus

Suosittelen kuitenkin, että aivan ensimmäisenä testailet Arduino-alustan käyttöä muuten (ledi vilkkumaan jne.) ja sitten kytket kiinni kosketuspaneelin oppaan ohjeiden mukaisesti. Tämän jälkeen porttaat koodiin mukaan PWM-toiminnallisuutta ja ohjailet 5 millimetrin RGB-lediä, joka ei vaadi muuta kuin sopivat etuvastukset (noin 330 ohmia). Viimeisenä lisäät tehokkaampia ledejä ja rakennat transistoreille piirilevyn joko reikälevystä tai syövytät oikean.

Mille alustalle teit koodia? Wikipediasta löytyy HUE:sta paljon tietoa ja muun muassa laskukaavat eri väriliu’uille.

Ajatus oli Atmelliin se kirjoittaa, mutta ihan Linux alustalla naputtelin. Mainin olisi joutunut kirjoittaan uudelleen. Nykyinen main toimii kolmella tapaa. gcc -lm -o xy-rgb xy-rgb.c tulostaa terminaaliin 20x20 tekstiläjän. Siis 20 väriarvoa taulukossa. laittamalla -DHTML saa 200x200 html taulukon, jossa solujen taustat on väreissä ja -DDEBUG tulostaa dataa eri tieteoa laskennan arvoista. arvoina käytetään X:n ja Y:n alustusarvoja.

Kehno tuo on siinä mielessä, että siinä on liikaa liukulukuja ja jakolaskuja. Mutta tyylikäs käli olisi. keskellä valkea, reunoilla puhtaat värit ja ne neljä nappia. Kauniisti nuo värit calcissa tulivat, mutta ehkä jossain vaiheessa kun on aikaa niin viilaan sen kuntoon. Ehkä laitan vielä tuollaisen lääpintämoduulin ja otan käyttöön tuon graaffisen näytön ja karvan verran jäykemmän kontrollerin tai sitten olen masokisti ja etsin jonkun aivan liian kevyen ja laitan sen siinä pyörimään. Olisi vain enempi aikaa itselle ja niille jutuille joista tykkää. Vuorokauden 24 tuntia on aivan liian vähän ja niistäkin nukkuminen vie ihan liikaa.