http://www.rcgroups.com/forums/showthread.php?t=1749208
Trochę podpicowałem, podszlifowałem, przerobiłem na ATtiny85 i jak ulał, razem z baterią ze starego telefonu mieści się w pudełku po tic-tacach.
https://www.youtube.com/watch?v=2ueq3XEYibU
Do szczęścia potrzeba:
moduł z ATttiny85,
moduł z czujnikiem ciśnienia BMP180.
Na aliexpress jedno i drugie po dolarku Do pełni szczęścia trzeba w szpargałach wygrzebać jakiś głośniczek ze starego telefonu i baterie.
Łączymy:
attiny85 ---- bmp180
p0 --- sda
p2 --- scl
5v --- vcc
gnd --- gnd
plus głośnika na p4 attiny85, minus na gnd.
Opcjonalnie, jeśli attiny ma kontrolować poziom baterii, 2 rezystory 220kOm i 1MOm.
Programowanie opisałem w poście http://pgforum.pl/viewtopic.php?f=17&t=256
UWAGI:
1. u mnie, na windows10, jeśli natychmiast po wgraniu programu do attiny nie wyciągnę modułu z portu usb, port staje się niedostępny i muszę restartować komputer aby móc ponownie wgrać progam - nie pomaga reinicjowanie portu i inne czary. Więc jeśli chcesz testowo zasilać moduł z PC, to podłóż coś pod wewnętrzne piny D- D+ w porcie USB.
2. u siebie zasilanie pomiędzy modułami poprowadziłem przez dławiki 10uH. Nie jest to niezbędne, ale powinno zwiększyć dokładność pomiaru ciśnienia.
3. w stosunku do oryginału, usunąłem sygnalizację opadania, bo IMHO, ciągłe brzęczenie było upierdliwe. Teraz vario pika tylko przy wznoszeniu.
Kod: Zaznacz cały
//http://www.rcgroups.com/forums/showthread.php?t=1749208&page=7
//attiny85, 1MHz
#include <TinyWireM.h>
#include <tinyBMP085.h>
#include <util/delay.h>
#define SPEAKER 4
#define LED 1
//CTC, toggle OC1B, clk/4, f=CLK/2*PSC*OCR1A, 255=4905Hz, 50=2.5kHz
#define PLAYER_START TCNT1=0; TCCR1 = _BV(CTC1) | _BV(CS11) | _BV(CS10)
#define PLAYER_STOP TCCR1=0
void myTone(uint16_t frequency);
void myNoTone(void);
tinyBMP085 sensor;
bool playing=0;
float toneFreq, toneFreqLowpass, pressure, lowpassFast, lowpassSlow;
int ddsAcc;
void setup()
{
pinMode(SPEAKER, OUTPUT);
pinMode(LED, OUTPUT);
if (!sensor.begin(BMP085_STANDARD)){
digitalWrite(LED, HIGH); // LED ON
while(1);
}
else
for(uint8_t i=0; i<10; i++)
{
digitalWrite(LED, !digitalRead(LED)); // LED toggle
_delay_ms(500);
}
digitalWrite(LED, LOW); // LED OFF
pressure = sensor.readPressure();
lowpassFast = pressure;
lowpassSlow = pressure;
//timer 1 - PLAYER
GTCCR = _BV(COM1B0); // toggle P4
//timer 1 - koniec
}
void loop()
{
pressure = sensor.readPressure();
// compute vario signal
lowpassFast = lowpassFast + (pressure - lowpassFast) / 10.0;
lowpassSlow = lowpassSlow + (pressure - lowpassSlow) / 20.0;
toneFreq = (lowpassSlow - lowpassFast) * 50;
toneFreqLowpass = toneFreqLowpass + (toneFreq - toneFreqLowpass) / 10.0;
toneFreq = constrain(toneFreqLowpass, -500, 500);
// direct digital synthesizer accumulator
// int wrapping around is the trick here
// loop timing definitely matters when picking these constants
ddsAcc += toneFreq * 100 + 2000; //http://en.wikipedia.org/wiki/Direct_digital_synthesizer
if ( (toneFreq > 30) && (ddsAcc > 0) )
myTone( toneFreq + 510);
else
myNoTone();
}
void myTone(uint16_t frequency)
{
if(playing==0){
PLAYER_STOP;
OCR1B = F_CPU/(frequency << 3); // PSC=4, F_CPU/(f*2*PRESCALER)
OCR1C = OCR1B;
PLAYER_START;
playing=1;
}
}
void myNoTone(void)
{
PLAYER_STOP;
playing=0;
}