Ciao a tutti,
sono Marco e questo è il mio primo post sul forum.
Stò facendo il mio primo progetto con Arduino, e si tratta di ricostruire con componenti Thought Hole questo spelndido orologio:
http://www.vonnieda.org/tc18
e aggiungere funzionalità. Arrivo dalla programmazione PIC, ma questo è il mio primo progetto con arduino e processori AMTEL.
Ho questo problema. Il circuito dell'orologio, ha un Booster che trasforma i 9 Volt di alimentazione in 30-60 Volt per alimentare il display. Questa tensione, viene generata da un circuito Booster L-C ( qua il princicpio Make a simple boost converter).
La tensione generata viene re-inmessa dento all'Arduino tramite un partitore sul Pin ADC0, e poi elaborata per mantenere l'alta tensione stabile.
Ho preso il codice originale dell'orologio e lo sto riadattando, ma non riesco a fare una cosa. Vorrei mettere sul pin ADC2 una fotoresistenza e poi avere anche la regolazione automatica della luminosità, ma per come l'autore ha scritto il codice non riesco a fare 2 letture diverse dall'ADC.
Posto il codice di impostazione dell'ADC:
// Internal 1.1V Voltage Reference, Single Ended Input on ADC0
ADMUX = _BV(REFS1) | _BV(REFS0);
// ADC Enable, ADC Auto Trigger Enable, ADC Interrupt Enable
// ADC Prescaler 128
ADCSRA |= _BV(ADEN) | _BV(ADATE) | _BV(ADIE)
| _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0);
// ADC Start Conversion (starts free running mode)
ADCSRA |= _BV(ADSC);
Il codice è commentato bene e per quello che capisco, fa partitr l'ADC in Free Running. Mi sono documento e ho capito che si tratta di una modalità che permette all'ADC di effettuare letture continue, e scatenare un Interrupt, quando una lettura è discponibile.
Infatti vi posto la routine di interrupt come l'ho modificata io, ma non funziona:
ISR(ADC_vect) {
uint8_t tmp; // temp register for storage of misc data
tmp = ADMUX; // read the value of ADMUX register
tmp &= 0x0F; // AND the first 4 bits (value of ADC pin being used)
low = ADCL;
high = ADCH;
if (tmp == 0){
if (voltage_sample++ > 20) {
voltage_sample = 0;
int adc = (high << 8) | low;
voltage = 1.066f / (0x3ff - 1) * adc * 112.344;
// We don't let the boost generator go below 10 or above 230
// Those equate to roughly VCC and 60v so allowing it to
// go too high can start blowing up components.
if (voltage > voltage_target + voltage_drift && OCR2B > 10) {
OCR2B--;
}
else if (voltage < voltage_target - voltage_drift && OCR2B < 230) {
OCR2B++;
}
}
ADMUX = ADMUX+2; // add 1 to ADMUX to go to the next sensor
}
else if (tmp == 2){
// put ADCvalue into whatever register you use for ADC2 sensor
//ADMUX &= 0xF6; // clear the last 4 bits to reset the mux to ADC0
light = (high << 8) | low;
ADMUX &= 0xF8;
//Serial.println(light);
}
}
A quanto ho capito devo leggere gli ultimi 4 bit del registro ADMUX per capire che porta dell'ADC sto leggendo, fare la lettura di ADCL e ADCH, e poi a seconda di ADMUX ho il valore della porta che mi interessa.
Invece non è così, se eseguo questo codice sull'orologio, sembra che la fotoresistenza collegata al pin ADC2 prenda il sopravvento, e mi regoli la luminosità del display entrando nella routine quando tmp==0. Ho provato anche con altri ingressi ma nulla cambia.
Ho cercato un po' in giro ma non ho trovato molto aiuto.
Grazie a tutti
PS è un Arduino UNO, quindi ATMEGA 328P
PSS Mi piace cominciare subito con qualcosa di difficile, altrimenti non c'è gusto