This crazy little bird never stops twittering on sunny days. It's a solar powered AtTiny13. Feel free to experiment with your own twitter, it's a good way to get into the programming of micro controllers!
Digital
Der digitale Solarvogel ist der kleine Bruder einer analogen Version, u.a. entwickelt von Ralf Schreiber. Im Gegensatz zu dieser sind in der digitalen Version die Abfolgen der Töne und Pausen zwar durch das Programm determiniert, dieses ist jedoch mit den meist mehrfach sich überlagernden Routinen "kaum" durchschaubar und erfrischend natürlich.
Zum Einsatz kommt ein Mikrocontroller des Typs AtTiny13 von Atmel. Das Programm, das darauf gespielt wird ist denkbar einfach.
Der Solarvogel basiert auf der von Christoph Haberer entwickelten Version. Während der HomeMade Woche in Vico Morcote 2012 hat Christoph dabei die next-generation nervtötender Vögel erzeugt, die zusätzlich einen Lichtsensor besitzen.
Check out the Hands on AVR wiki page for introduction into AtTiny programming!
Durch die Stromversorgung mit der Solarzelle, die den Chip ständig unterversorgt, ist der AtTiny13 jedoch ziemlich instabil, wenn es darum geht, Buttons oder Sensoren mit anzuhängen. Dafür lässt sich mit der variablen Stromzufuhr, das heisst durch Abdecken der Solarzelle, oder bei kurzzeitig vorüberziehenden Wolken, die Taktfrequenz des Chips verlangsamen. Das hat zur Folge, dass auch die Frequenzausgabe verlangsamt wieder; man kann also quasi die Tonhöhe mit der Solarzelle als Sensor steuern.
Der Typ AtTiny13 wurde von Atmel überarbeitet und in einer neuen Version AtTiny13A mit dem Zusatz "A" herausgegeben. Dieser neue Typ hat leider nicht mehr das gleiche Verhalten bei Unterversorgung. Deshalb ist diese Version für den Bausatz nicht mehr geeignet. Falls der alte Typus nicht mehr erhaltbar ist, wir haben sie noch. Und auch wenn du noch fragen hast, komm doch einfach vorbei ins OpenLab, jeden Dienstag um 20h.
komplettes Codebeispiel
/*************************************************************************
SOLAR BIRD, OISILLON, SOLARVOGEL
attiny13 power experiments
28.9.08 christoph(at)roboterclub-freiburg.de
15.5.11 urban.bieri(at)mechatronicart.ch
*************************************************************************/
/*************************************************************************
Hardware
prozessor: ATtin13
clock: 1.2 Mhz internal oscillator
PIN5, PORTB0/OC10: piezo controll speaker
*************************************************************************/
#include <avr/io.h>
#define PIEZOSPEAKER (1<<PINB0)
//GLOBAL VARIABLES
uint16_t tone_d = 100;
uint16_t pause_d = 500;
int8_t pitchstep = 1;
void init_timer()
{
DDRB |= PIEZOSPEAKER; // Piezo as output
TCCR0A=(1<<COM0A0) | 0x02; //CTC mode and toogle OC0A port on compare match
TCCR0B=(1<<CS00) ; // no prescaling,
OCR0A=255; // in CTC Mode the counter counts up to OCR0A
}
void delay_ms(uint16_t duration)
{
uint16_t d;
uint8_t n;
uint16_t counter;
counter=(3*duration);
// periode duration ??
for(d=0;d<counter;d++)
{
for(n=0;n<1;n++) PORTB &= ~(PIEZOSPEAKER);
for(n=0;n<1;n++) PORTB &= ~(PIEZOSPEAKER);
}
}
#define SPEAKEROFF TCCR0A=(0x02)
#define SPEAKERON TCCR0A=((1<<COM0A0) | 0x02)
void invokePattern1(uint16_t duration, uint16_t pause, int8_t pitchstep){
OCR0A -= pitchstep;
delay_ms(duration);
OCR0A -= pitchstep;
delay_ms(duration);
OCR0A -= pitchstep;
delay_ms(duration);
OCR0A += (2*pitchstep);
SPEAKEROFF; //PAUSE!
delay_ms(pause);
SPEAKERON;
}
void invokePattern2(uint16_t duration, uint16_t pause, int8_t pitchstep){
delay_ms(duration<<1);
OCR0A -= pitchstep+4;
SPEAKEROFF; //PAUSE!
delay_ms(pause<<2);
SPEAKERON;
}
int main(void)
{
uint8_t i; //working variable
// Initiation
OCR0A = 255;
init_timer();
while(1)
{
for(i=0; i<4; i++){
invokePattern1(tone_d, pause_d, pitchstep);
if(0b00000100==4)pitchstep++;
tone_d += 20;
pause_d -= 5;
}
invokePattern2((tone_d<<1), (pause_d<<2), pitchstep);
if(OCR0A<=16)OCR0A=255;
if(pitchstep>32)pitchstep=1;
if(tone_d>200)tone_d=20;
if(pause_d<20)pause_d=200;
if(pitchstep<8 && OCR0A<40){
tone_d=1;
pitchstep = 0;
}
}
return 0;
}
/***************************************************************************
*
* (c) 2008 christoph(at)roboterclub-freiburg.de
* 2011 urbanbieri(at)gmx.ch
*
***************************************************************************
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation version 2 of the License, *
* If you extend the program please maintain the list of authors. *
* If you want to use this software for commercial purposes and you *
* don't want to make it open source, please contact the authors for *
* licensing. *
***************************************************************************/
code snippet glissando
void invokeGlissando(uint8_t start, uint8_t stop, uint16_t duration, uint16_t pause){
uint8_t j; //working variable
if (start<= stop){
for(j=start;j<stop;j++){
OCR0A = j;
delay_ms(duration);
}
}else{
for(j=start;j>stop;j--){
OCR0A = j;
delay_ms(duration);
}
}
// SPEAKEROFF;
delay_ms(pause);
// SPEAKERON;
}
int main(void)
{
uint8_t i; //working variable
// Initiation
OCR0A = 255;
init_timer();
while(1)
{
for(i=0; i<245; i+=stepsize){
invokeGlissando(start_0, stop_0, tone_d, pause_d);
invokeGlissando(start_1, stop_1, tone_d, pause_d);
start_0 += 1;
stop_0 += 2;
start_1 -= 3;
stop_1 -= 7;
tone_d += 1;
pause_d -= 2;
if(start_0>=240) start_0=0;
// if(stop_0>=253) stop_0=0;
if(stop_0-start_0>15) stop_0=start_0;
if(start_1<127) start_1=255;
// if(stop_1<95) stop_1=255;
if(start_1-stop_1>31) stop_1=start_1;
if(tone_d>20)tone_d=1;
if(pause_d<2)pause_d=20;
}
if(stepsize<=32){
stepsize = stepsize<<1;
}else{
stepsize = 1;
}
SPEAKEROFF;
delay_ms(200);
SPEAKERON;
}
return 0;
}











Kommentare (0)