Voltmeter mit optionaler Tonausgabe
von Hermann Nieder
Das Programm für ein Sparrow-Voltmeter
lässt sich so erweitern, dass auch recht gut Spannungswerte ab 10
Volt angezeigt werden können. Außerdem ist neben dem Blinken
einer LED nun auch eine Tonausgabe am PWM-Ausgang PB1 des ATtiny13
möglich, wenn man gerade einen Piezo-Schallgeber oder einen kleinen
Lautsprecher und einen geeigneten Vorwiderstand zur Verfügung hat.
Da
der Programmspeicher des Mikrocontrollers mit dem ursprünglichen
Programm schon ziemlich „voll“ war (486 von 512 Words), musste
nun bei der Gestaltung des neuen Listings Platz eingespart werden. So
entfällt in der hier vorliegenden Version das Blinken der grünen
LED auf der Sparrow-Platine im Rhythmus von Morsezeichen. Außerdem
fehlen einige Wartezeiten.
Nun können auch
Spannungswerte über 10V angezeigt werden. Der „Dezimalpunkt“ wird
in diesen Fällen an der „richtigen“ Stelle „gesetzt“.
Die Tonausgabe in der erweiterten Programmversion wurde in Anlehnung an B. Kainkas Beispiel-Programm „Sparrow_TeleBin.bas“ gestaltet.
Die
Morsezeichen werden bei einer Betätigung von S2 ähnlich
wie bei der ursprünglichen Programm-Version mithilfe der roten
LED sichtbar gemacht. Zusätzlich ist der PWM-Ausgang aktiviert,
damit entsprechende Töne mit einem Piezo-Schallgeber oder
einen kleinen Lautsprecher mit einem Vorwiderstand hörbar gemacht
werden können.
Beim Betätigen von S1 erfolgt in ähnlicher Weise
die Ausgabe des betreffenden Bytes, das der an ADC2(PB4) anstehenden
Spannung entspricht.
Es wurde Platz im C-Programm gespart, indem
darin nun nur noch eine einzige Variable des Formats „unsigned long“
„AD_wert“ verwendet wird.
In der nun vorliegenden Version des
Programms wird beim Drücken von S2 zuerst die Dezimalzahl des
Spanungswertes angezeigt und „hörbar“ gemacht. Anschließend
werden alle vier Zeichen für das Wort „VOLT“ wiedergegeben.
Das Trimmpoti am Eingang ADC2(PB4) des ATtiny13
lässt sich auch z. B. mithilfe eines Digitalmultimeters auf andere
Werte einstellen, um mit dem Sparrow-Voltmeter z. B. Spannungen
bis maximal ca. 5.5 V zu bestimmen. In diesem Fall muss
allerdings der Umrechnungsfaktor im Programmlisting auch neu festgelegt
werden, bevor das C-Programm erneut kompiliert und die veränderte
HEX-Datei z. B. mithilfe des „SoundProgrammers“ von Thomas Baum in den Mikrocontroller übertragen werden kann.
Die
Möglichkeit einer „Byte-Anzeige“ der Messspannung an ADC2 beim
Drücken von S1 auf der Sparrow-Platine und anschließendes Rechnen mit
einem Taschenrechner sowie Vergleichs-Messungen mit einem
Digitalmultimeter (Ri: 10 MOhm) erweist sich beim
„Eichen“ des Sparrow-Voltmeters im Betrieb als sehr
nützlich. Dies hatte ich schon beim Erproben der ersten Programmversion
herausgefunden.
Die HEX-Datei zur erweiterten Programmversion belegt mit 512 Words den kompletten Programmspeicher des ATtiny13.
Download: Sp_Spg2_T13.zip
Direkt laden: http://tiny.systems/categorie/cheepit/Voltmeter10VSound.html
/* Sp_Spg1.c */
/* 10.03.2015*/
#include <avr/io.h>
#include <util/delay.h>
unsigned long AD_wert;
int AD_dat,Ziffer,U,U_anzg,Urest;
#define setbit(P,BIT) ((P) |= (1<<(BIT)))
#define clearbit(P,BIT) ((P) &=~(1<<(BIT)))
void Blink_rt_k()
{
setbit(PORTB,PB3);
OCR0B=80;
_delay_ms(150);
clearbit(PORTB,PB3);
OCR0B=0;
_delay_ms(150);
}
void Blink_rt_L()
{
setbit(PORTB,PB3);
OCR0B=80;
_delay_ms(450);
clearbit(PORTB,PB3);
OCR0B=0;
_delay_ms(150);
}
void Tonausgabe()
{
switch(Ziffer)
{
case 0:
Blink_rt_L();// Bezeichnungen in Anlehnung
Blink_rt_L();// an Sparrow-Voltmeter
Blink_rt_L();// mit "LED-Morsezeichen"
Blink_rt_L();
Blink_rt_L();
_delay_ms(300);
break;
case 1:
Blink_rt_k();
Blink_rt_L();
Blink_rt_L();
Blink_rt_L();
Blink_rt_L();
_delay_ms(300);
break;
case 2:
Blink_rt_k();
Blink_rt_k();
Blink_rt_L();
Blink_rt_L();
Blink_rt_L();
_delay_ms(300);
break;
case 3:
Blink_rt_k();
Blink_rt_k();
Blink_rt_k();
Blink_rt_L();
Blink_rt_L();
_delay_ms(300);
break;
case 4:
Blink_rt_k();
Blink_rt_k();
Blink_rt_k();
Blink_rt_k();
Blink_rt_L();
_delay_ms(300);
break;
case 5:
Blink_rt_k();
Blink_rt_k();
Blink_rt_k();
Blink_rt_k();
Blink_rt_k();
_delay_ms(300);
break;
case 6:
Blink_rt_L();
Blink_rt_k();
Blink_rt_k();
Blink_rt_k();
Blink_rt_k();
_delay_ms(300);
break;
case 7:
Blink_rt_L();
Blink_rt_L();
Blink_rt_k();
Blink_rt_k();
Blink_rt_k();
_delay_ms(300);
break;
case 8:
Blink_rt_L();
Blink_rt_L();
Blink_rt_L();
Blink_rt_k();
Blink_rt_k();
_delay_ms(300);
break;
case 9:
Blink_rt_L();
Blink_rt_L();
Blink_rt_L();
Blink_rt_L();
Blink_rt_k();
_delay_ms(300);
break;
default:
break;
}
}
void AD_start()
{
ADCSRA |= (1<<ADSC); // ADC starten
while(ADCSRA & (1<<ADSC));
ADCSRA |=(1<<ADSC);
while(ADCSRA & (1<<ADSC));
}
void Anzeige_bt()
{
AD_dat=ADCH;
Ziffer=AD_dat/100;
Tonausgabe();
U=AD_dat%100;
U_anzg=U/10;
Urest=U%10;
Ziffer=U_anzg;
Tonausgabe();
Ziffer=Urest;
Tonausgabe();
//_delay_ms(300);
//Blink_rt_L(); // Zeichen "D"
//Blink_rt_k(); // fuer "dezimale"
//Blink_rt_k(); // Anzeige eines Bytes
}
int main(void)
{
DDRB=0b00001010; // PORTB.1 und PORTB.3 sind Ausgaenge
ADCSRA =(1<<ADEN)|(1<<ADPS1)|(1<<ADPS0);// Division Fact. 8
ADMUX=(1<<REFS0)|(1<<ADLAR)|(1<<MUX1); //int . Referenz, 8-Bit-Messung
// ADC2 (PB4)
TCCR0A=0b00100011; // PWM b
TCCR0B=0b00000010; // Vorteiler /8
OCR0B=0;
while(1)
{
if(!(PINB &(1<<PB0)))//if 1
{
AD_start();
Anzeige_bt();
} //end if 1
if(!(PINB &(1<<PB2)))//if 2
{
AD_start();
_delay_ms(1000);
AD_wert=ADCH;
AD_wert=AD_wert*43; // wegen 1.1/255=0.0043
AD_wert=AD_wert*11; // Umrechnungsfaktor,
// mithilfe von
// D.-Multimeter ermittelt
if (AD_wert>100000)// if 3
{
Ziffer=AD_wert/100000;
Tonausgabe();
AD_wert=AD_wert-100000;
} // end if 3
Ziffer=AD_wert/10000;
Tonausgabe();
Blink_rt_k();//"Dezimalpunkt"
Blink_rt_L();//
Blink_rt_k();
Blink_rt_L();
Blink_rt_k();
Blink_rt_L();
_delay_ms(300);
AD_wert=AD_wert%10000;
Ziffer=AD_wert/1000;
AD_wert=AD_wert%1000;
Tonausgabe();
Ziffer=AD_wert/100;
Tonausgabe();
Blink_rt_k(); //Zeichen "V"
Blink_rt_k();
Blink_rt_k();
Blink_rt_L();
_delay_ms(300);
Blink_rt_L(); //Zeichen "O"
Blink_rt_L();
Blink_rt_L();
_delay_ms(300);
Blink_rt_k(); //Zeichen "L"
Blink_rt_L();
Blink_rt_k();
Blink_rt_k();
_delay_ms(300);
Blink_rt_L(); //Zeichen "T"
_delay_ms(300);
} // end if 2
} // end while(1)
} // end main