"Claudio_F" ha scritto nel messaggio news: snipped-for-privacy@db5g2000vbb.googlegroups.com...
Uhm, era per multiplexare le fotoresistenze.
Insomma, non ho ancora capito se Arduino ha ingressi a sufficienza per i 6 trimmer (2 coppie di 3 assi) e la fotoresistenza x4. Ricordiamoci che ci sono i deviatori del selettore AUTO/semiauto/MANUAL nel caso in cui si implementano le fotoresistenze e altri due ingressi dei pulsanti dei joystick.
Oggi e' arrivato l'Arduino, ma ho avuto solo il tempo di aprirne la scatolina. E per qualche giorno sara' cosi'.
E quindi ti servono: 10 in analogici 4 out digitali PWM 2 in digitali pulsanti
Piu' quello che serve per comandare il mux e leggere il commutatore di modo (quest'ultimo potrebbe anche essere realizzato con un ingresso analogico e un partitore di tensione).
Ad esempio, se si usasse il mux 4051 si potrebbero leggere i joy con 6 dei suoi ingressi, e con gli altri 5 Ain di Arduino leggere il selettore di modo e le 4 fotoreistenze. A questo punto per comandare il mux servirebbero solo 3 out digitali, che assieme ai 4 PWM e ai due pulsanti fanno 9 ingressi/uscite digitali (avremmo tutto e avanzerebbe ancora qualcosa).
Prima devi scoprire gli end-point dei potenziometri del joystick, cioe' i valori che vengono letti dagli ingressi analogici quando vengono portati a fondocorsa. Colleghi il cursore del trimmer/potenziometro al terminale A0 e gli estremi a +5V e massa, visualizzi i valori col terminale che apri dall' IDE. Scrivo in forma didattica quasi stile "lesson-01":
//---------------------------------------------------------- // Variabili globali del programma // (in cui memorizzare i dati di lavoro) //----------------------------------------------------------
int n; //Variabile intera, contiene da -16384 a +16383
//---------------------------------------------------------- // Funzione setup, settaggi iniziali // (istruzioni eseguite una sola volta all'inizio) //----------------------------------------------------------
void setup() { Serial.begin(9600); //Predispone porta seriale }
//---------------------------------------------------------- // Funzione loop, ciclo principale del programma // (istruzioni eseguite continuamente) //----------------------------------------------------------
void loop() { n = analogRead(0); //Legge da ingresso analogico 0 Serial.println(n); //Scrive valore su seriale delay(100); //Attende 0.1 secondi }
anche se non partecipo, vi seguo, e vorrei continuare a non partecipare perche' non oso immaginare cos'altro chiederai in futuro! :))
comunque ho pensato al circuito seguente per multiplexare i 2 joystick usando solo arduino attraverso una manciata di diodi e 2 uscite per selezionare il joystick
non l'ho provato ma credo che funzioni.
[FIDOCAD] MC 40 90 0 0 114 MC 30 100 0 0 114 LI 50 105 35 105 LI 40 100 40 105 MC 95 100 0 0 114 MC 85 110 0 0 114 LI 105 115 90 115 MC 150 110 0 0 114 MC 140 120 0 0 114 LI 160 125 145 125 TY 195 90 5 3 0 0 0 * A0 TY 195 100 5 3 0 0 0 * A1 TY 195 110 5 3 0 0 0 * A2 TY 20 100 5 3 0 0 0 * 10k LI 140 140 140 130 LI 85 140 85 120 LI 30 140 30 110 SA 85 140 SA 140 140 RV 195 85 225 130 TY 205 85 5 3 0 0 0 * D13 TY 215 85 5 3 0 0 0 * D12 TY 215 95 5 3 0 0 0 * D11 TY 215 100 5 3 0 0 0 * D10 TY 215 105 5 3 0 0 0 * D9 TY 215 110 5 3 0 0 0 * D3 LI 225 100 235 100 LI 235 105 225 105 LI 225 110 235 110 LI 235 115 225 115 TY 240 100 5 3 0 0 0 * PWM SA 125 105 SA 70 95 SA 180 115 LI 195 115 175 115 LI 195 105 120 105 LI 195 95 65 95 MC 50 95 0 0 200 MC 50 105 0 0 200 MC 105 115 0 0 200 MC 105 105 0 0 200 MC 160 115 0 0 200 MC 160 125 0 0 200 SA 95 140 SA 150 140 LI 40 105 40 140 LI 95 110 95 140 LI 150 120 150 140 SA 85 75 SA 95 80 SA 140 75 SA 150 80 LI 215 85 215 75 LI 40 80 205 80 LI 215 75 30 75 LI 205 80 205 85 LI 150 80 150 110 LI 140 75 140 120 LI 95 100 95 80 LI 85 75 85 110 LI 40 80 40 90 LI 30 75 30 100 LI 45 95 50 95 LI 65 105 70 105 LI 100 105 105 105 LI 120 115 125 115 LI 155 115 160 115 LI 175 125 180 125 SA 30 140 SA 40 140 MC 30 140 1 0 200 MC 30 155 0 0 045 MC 70 155 0 0 045 MC 125 155 0 0 045 MC 180 155 0 0 045 MC 180 130 0 0 115 MC 125 120 0 0 115 MC 70 110 0 0 115 LI 70 95 70 110 LI 125 120 125 105 LI 180 130 180 115 LI 70 120 70 155 LI 125 155 125 130 LI 180 140 180 155 SA 70 105 SA 125 115 SA 180 125 MC 170 140 1 0 115 LI 30 140 160 140 LI 170 140 205 140 LI 205 140 205 130 TY 205 125 5 3 0 0 0 * 5v TY 55 115 5 3 0 0 0 * 100k TY 165 135 5 3 0 0 0 * 1k TY 55 85 5 3 0 0 0 * 4148
"Claudio_F" ha scritto nel messaggio news:4f6cbaea$0$1384$ snipped-for-privacy@reader1.news.tin.it...
Lo faronsi, da martedi, come dice ad Alfio. Oggi ero dallo spacciatore di minuzzaglie e ho preso anche un paio di 4051 per multiplexare le fotoresistenze.
Naaa... vedrete che sara' una passeggiata. E comunque arduino sara' un frontend per i led: alla fine posso modificare quel che voglio senza toccare la grondaia e la configurazione del led, ne' i power mosfet.
Diciamo che fino al joystick, al pulsante on/off, e allo switch per attivare il fading automatico ci si arriva.
Il multiplex di un altro joy+pulsante si dovrebbe poter implementare non troppo drammaticamente (ma dovrai rileggere tutti gli end point perche'il convertitore analogico-digitale leggera' valori diversi).
Le fotoresistenze invece le vedo molto incasinate, forse bisognerebbe studiare un mdello matematico (che non so fare), potrebbero esserci problemi di oscillazioni (luci che continuano ad alzarsi e abbassarsi), e bisognerebbe anche filtrare bene (l'occhio il PWM non lo vede ma le fotoresistenze lo vedono benissimo).
Dici? Intanto ho gia' fatto le 4 di mattina per studiare il fader, il pulsante e la miscelazione delle luminosita' nelle diagonali :-P Giusto bene che lo sto prendendo come esercizio personale di C e di Arduino.
La buona notizia e' che e' molto piu' veloce ad elaborare di quanto mi aspettavo anche usando aritmetica floating point (questo semplifica molto le cose). Il ciclo del programma infatti non raggiunge neanche 1.5 millisecondi, per cui e' molto comodo crearsi un tempo base di 20 ms con cui portare avanti gli stati dell'elaborazione, applicare l'anti rimbalzo al pulsante, e conteggiare i tempi.
"Claudio_F" ha scritto nel messaggio news:4f6dc9b1$0$1380$ snipped-for-privacy@reader2.news.tin.it...
Faronsi.
Si certo. Ma tieni presente che le fotoresistenze saranno messe per leggere la luce ambiente, non quella diretta dei led e che comunque si sommera' alla luce ambiente.
Certo, si dovra' studiare una buona isteresi per non entrare in autooscillazione. In fondo il lavoro principale e' quello di sostituire il joystick piuttosto che fungere da banale "dimmer automatico".
Infatti ho previsto una posizione semiauto del selettore in modo che la luminosita' totale (il master) la decidera' comunque l'asse Z del potenziometro attivo in quel momento. Il valore letto dalle fotoresistenze dira' soltanto dove ci dovra' andare piu' luce, sostituendosi agli assi X e Y. Volendo semplificare potremmo anche omettere l'asse Z automatico se cio' comporta problemi di autooscillazione.
Se non ho interpretato male il "semiauto", quello (con 1 joy) e' gia' fatto :-P Ho dovuto anche aggiungere una media mobile delle letture su
10 campioni perche' "tremolvano"...
//-------------------------------------------------------------------- // C A R L E T T O L I G H T S . . . with fader // Program by Claudio Fin - 24/3/2012 //-------------------------------------------------------------------- // A0 10000) atteso += 20; // gestione rollover if (actual < atteso) return false; atteso += 20; return true; }
il programma di Claudio ti serve lo stesso per capire il range in cui operano i 3 potenziometri. nel mio codice trovi le variabili:
word minNS=0; // min&max per tarare il range dei potenziometri word maxNS=1023; word minWE=0; word maxWE=1023; word minMA=0; word maxMA=1023;
i valori fissi 0 e 1023 vanno sostituiti con il risultato del programma di Claudio.
poi se vuoi ci si puo' mettere una scrittura da linea seriale, cosi' li imposti o modifichi dal PC, oppure una autotaratura, ossia si impostano da soli ruotando il potenziometro, ma in questi 2 ultimi casi il tutto va memorizzato su eeprom interna e riletto all'accensione. :')
"Claudio_F" ha scritto nel messaggio news:4f6e0e29$0$1388$ snipped-for-privacy@reader2.news.tin.it...
No. E' sempre con 2 joystick.
Il semiauto e manual e' riferito solo al fatto che in manual e' il joystick che decide dove deve andare la luce, in semiauto e' il programma che lo decide in funzione della lettura delle fotoresistenze. In entrambi i casi il master e' demandato all'asse Z del joystick.
Ah, ok, allora per il manuale dovremmo essere e posto con questo (i joy vanno attaccati ai primi 6 ingressi del 4051, e fader sempre inserito con tempo regolabile via trimmer). Per il semi/full invece passo :-P
Il programma occupa 5K, l'elaborazione completa avviene in 1.9ms e viene ripetuta circa 200 volte al secondo. Speravo di tenerlo "semplice" in modo che fosse anche didattico, ma no ja fo'... (tra l'altro e' il mio primo programma in C).
Per dubbi sui collegamenti fischia.
//-------------------------------------------------------------------- // C A R L E T T O L I G H T S // With: fader - double joypad master/slave - multiplexed analog read // Program by Claudio Fin - 25/3/2012 //--------------------------------------------------------------------
//-------------------------------------------------------------------- // Variabili globali del programma //--------------------------------------------------------------------
# define minNS 30 // end points potenziometri NS WE MA # define maxNS 910 // da sostituire con i valori misurati # define minWE 30 // ridotti di 20 verso centro scala (512) # define maxWE 910 # define minMA 30 # define maxMA 910 # define maxTimeFader 5 // max tempo fader in secondi
float master; // calcolo luminosita' generale da 0.0 a 1.0 float nAtt; // attenuazione nord float sAtt; // attenuazione sud float eAtt; // attenuazione est float wAtt; // attenuazione ovest float neAtt; // attenuazione diagonale ne float nwAtt; // attenuazione diagonale nw float seAtt; // attenuazione diagonale se float swAtt; // attenuazione diagonale sw
int asseX = 0; // lettura joy asse est-ovest int asseY = 0; // lettura joy asse nord-sud int asseZ = 0; // lettura joy luminosita' globale int preNS[10] = {0,0,0,0,0,0,0,0,0,0}; // letture precedenti int preWE[10] = {0,0,0,0,0,0,0,0,0,0}; int preMA[10] = {0,0,0,0,0,0,0,0,0,0}; int preIndice = 0; // indice array letture precedenti
byte statFader = 0; // stato task fader float stepFader; // step inc/dec valFader float valFader = 0.0; // uscita fader da 0 a 1
byte statLed = HIGH; // stato led Arduino byte contLed = 200; // conteggio blink
unsigned long actual = millis(); unsigned long atteso = actual;
int n; // variabile di lavoro intera float w; // variabile di lavoro float
//-------------------------------------------------------------------- // Settaggi iniziali //-------------------------------------------------------------------- void setup() { pinMode(5, OUTPUT); // indirizzo mux A pinMode(6, OUTPUT); // indirizzo mux B pinMode(7, OUTPUT); // indirizzo mux C pinMode(13, OUTPUT); // led Arduino }
//-------------------------------------------------------------------- // Ciclo principale del programma, chiama i processi ogni 5 ms //-------------------------------------------------------------------- void loop() { if (checkTime()) { pulsante(&statPuls1, &contPuls1, &premuto1, 2); // debounch pulsante(&statPuls2, &contPuls2, &premuto2, 4); // debounch masterSlaveLogic(); // logica di scambio joy attivo leggiIngressi(); // lettura ingressi analogici fader(); // task fader elabora(); // task elaborazione principale blinkLed(); // lampeggio lento led Arduino } }
//-------------------------------------------------------------------- // True se trascorsi almeno 5 millisecondi dal valore atteso //-------------------------------------------------------------------- boolean checkTime() { actual = millis(); while (atteso - actual > 10000) atteso += 5; // gestione rollover if (actual < atteso) return false; atteso += 5; return true; }
//-------------------------------------------------------------------- // Ritorna true se l'ingresso digitale n e' basso //-------------------------------------------------------------------- boolean pressed(byte n) { return true ? (digitalRead(n) == LOW) : false; }
//-------------------------------------------------------------------- // Applica antirimbalzo alla lettura dell'ingresso digitale n // Le variabili di lavoro sono passate per riferimento per usare // una sola funzione per entrambi i pulsanti. //-------------------------------------------------------------------- void pulsante(byte *stat, byte *cont, boolean *prem, byte n) { switch (*stat) {
case 0: // attesa pressione pulsante if (pressed(n)) { *stat = 1; *cont = 8; } break;
case 1: // verifica chiusura per 8 cicli if (!pressed(n)) { *stat = 0; break; } *cont = *cont - 1; if (*cont == 0) { *stat = 2; *prem = true; } break;
case 2: // attesa rilascio pulsante if (!pressed(n)) { *stat = 3; *cont = 8; } break;
case 3: // verifica rilascio per 8 cicli if (pressed(n)) { *stat = 2; break; } *cont = *cont - 1; if (*cont == 0) *stat = 0; } }
//-------------------------------------------------------------------- // Gestisce lo scambio tra joystick master e slave, invia al fader // il valore del pulsante attualmente premuto, e alla lettura ingressi // l'indicazione del joy attivo. //-------------------------------------------------------------------- void masterSlaveLogic() { switch (statMasterSlaveLogic) { case 0: premuto = premuto1; premuto1 = false; if (premuto2) { premuto2 = false; statMasterSlaveLogic = 1; } break;
case 1: premuto = premuto2; premuto2 = false; if (premuto1) { premuto1 = false; statMasterSlaveLogic = 0; } } }
//-------------------------------------------------------------------- // Legge assi joystik, mette i valori nelle variabili assexzy //-------------------------------------------------------------------- void leggiIngressi() { if (statMasterSlaveLogic == 0) // legge joy 1 { setMuxIndi(0); delayMicroseconds(100); asseY = constrain(analogRead(0), minNS, maxNS); setMuxIndi(1); delayMicroseconds(100); asseX = constrain(analogRead(0), minWE, maxWE); setMuxIndi(2); delayMicroseconds(100); asseZ = constrain(analogRead(0), minMA, maxMA); } else // legge joy 2 { setMuxIndi(3); delayMicroseconds(100); asseY = constrain(analogRead(0), minNS, maxNS); setMuxIndi(4); delayMicroseconds(100); asseX = constrain(analogRead(0), minWE, maxWE); setMuxIndi(5); delayMicroseconds(100); asseZ = constrain(analogRead(0), minMA, maxMA); } }
//-------------------------------------------------------------------- // Legge trimmer tempo fader e calcola step incrementi/decrementi //-------------------------------------------------------------------- int calcStepFader() { w = analogRead(3) / 1023.0 * maxTimeFader; // tempo fading (sec) w = 1.0 + w / 0.005; // numero di step stepFader = 1.0 / w; // valore step }
//-------------------------------------------------------------------- // Alla pressione del pulsante attivo avvia accensione/spegnimento. // Sono inevitabili dei piccoli gradini di luminosita' con basse // luminosita' ed elevati tempi di fading. //-------------------------------------------------------------------- void fader() // task fader { switch (statFader) {
case 0: // spento, attesa pressione pulsante if (premuto) { premuto = false; calcStepFader(); statFader = 1; } break;
case 1: // accensione con fading valFader += stepFader; if (valFader > 1.0) { valFader = 1.0; statFader = 2; } if (premuto) { premuto = false; statFader = 3; } break;
case 2: // acceso, attesa pressione pulsante if (premuto) { premuto = false; calcStepFader(); statFader = 3; } break;
case 3: // spegnimento con fading valFader -= stepFader; if (valFader < 0.0) { valFader = 0.0; statFader = 0; } if (premuto) { premuto = false; statFader = 1; } } }
//-------------------------------------------------------------------- // Calcola media mobile su 10 letture per evitare sfarfallio //-------------------------------------------------------------------- float mediaLetture(int *dati, int n) { dati[preIndice] = n; int somma = 0; for (int i=0; (i < 10); i++) somma += dati[i]; return somma / 10.0; }
//-------------------------------------------------------------------- // Effettua tutti i calcoli e comanda le uscite PWM //-------------------------------------------------------------------- void elabora() // elaborazione principale { // calcola attenuazioni nord/sud n = int(mediaLetture(preNS, asseY)); if (n>511) { nAtt = 0.0; sAtt = float(n - 512) / (maxNS - 512); } else { nAtt = 1.0 - float(n - minNS) / (511 - minNS); sAtt = 0.0; }
//-------------------------------------------------------------------- // Fine del palo :-P //--------------------------------------------------------------------
ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here.
All logos and trade names are the property of their respective owners.