BASCOM-zliczanie impulsów.

Pytania, kody i porady dotyczące nie tylko Bascom.
ODPOWIEDZ
Awatar użytkownika
pimowo
Posty: 392
Rejestracja: 28 maja 2016, 10:07

BASCOM-zliczanie impulsów.

Post autor: pimowo » 28 maja 2016, 23:00

Witam.
Chciałbym zliczać impulsy z sensorów: opadów deszczu i prędkości wiatru. Mikrokontroler jaki wybrałem to ATmega328P + kwarc 11059200
W moich urządzeniach jest kontaktron i według producenta połączenie powinno wyglądać tak:

Obrazek

Kod który "zmajstrowałem" wygląda tak: $regfile = "m328pdef.dat" $crystal = 11059200 $baud = 19200 Config Timer0 = Timer , Prescale = 1024 , Compare A = Disconnect , Compare B = Disconnect , Clear Timer = 1 Enable Compare0a : On Compare0a Int_10ms Nosave : Compare0a = 107 '10ms @11MHz 107 Dim 10ms As Byte , 100ms As Byte , 1s As Byte Dim Deszcz_licznik As Byte , Wiatr_licznik As Byte Dim Deszcz_ilosc As Byte , Wiatr_predkosc As Byte Config Portd.2 = Input : Portd.2 = 1 : Wiatr_sensor Alias Pind.2 Config Portd.3 = Input : Portd.3 = 1 : Deszcz_sensor Alias Pind.3 Config Int0 = Falling Enable Int0 : On Int0 Deszcz Nosave Config Int1 = Falling Enable Int1 : On Int1 Wiatr Nosave Deszcz_licznik = 0 Wiatr_licznik = 0 Enable Interrupts Print "START" Do If 10ms = 1 Then 10ms = 0 Incr 100ms End If If 100ms = 100 Then 100ms = 0 Incr 1s End If If 1s = 60 Then 1s = 0 Deszcz_ilosc = Deszcz_licznik Deszcz_licznik = 0 Wiatr_predkosc = Wiatr_licznik Wiatr_licznik = 0 Print Deszcz_ilosc ; " " ; Wiatr_predkosc End If Loop End Int_10ms: $asm PUSH R24 !in R24, sreg PUSH R24 $end Asm 10ms = 1 'Tuned with NoSave Tool $asm POP R24 !out sreg, r24 POP R24 $end Asm Return Deszcz: If Deszcz_sensor = 1 Then Incr Deszcz_licznik End If Return Wiatr: If Wiatr_sensor = 1 Then Incr Wiatr_licznik End If Return Prawdę mówiąc to nawet nie mam pojęcia od czego zacząć.
Będę wdzięczny za pomoc ;)
Awatar użytkownika
niveasoft
Posty: 1216
Rejestracja: 17 sie 2015, 12:13
Kontakt:

Re: BASCOM-zliczanie impulsów.

Post autor: niveasoft » 29 maja 2016, 9:23

Jeśli chodzi o schemat to przy pracy z zewnętrznymi przerwaniami w połączeniu z kontaktronami to dodałbym po kondensatorze ~100nF.
Widziałem taki design liczący prędkość roweru kontaktronem na widełkach i bez kondensatora "jechał z różnymi prędkościami" :D

Na razie nie mogłeś zaobserwować tego zjawiska bo robisz coś sprzecznego jedno z drugim.
Konfigurujesz wejscia na podciąganie wewnętrznymi rezystorami wbudowanymi w uC.
Potem konfigurujesz zewnętrzne przerwania na opadające zbocze, czyli wyzwalanie masą

Niestety kiedy pin jest zwarty do masy i program znajduje się w podprogramie obsługi przerwania to sprawdzasz czy pin ma wartość 1, czyli czy nie jest zwarty do masy . Czy to ma sens? :D

Pin jest zawarty do masy więc nigdy nie będzie miał 1 i nigdy niczego nie doda, ani nie policzy :D

Osobna sprawą jest użycie parametru Nosave przy włączaniu tych przerwań. Nie mając tego mojego programu nie możesz tak robić.

Nosave powoduje że Bascom nie odkłada żadnych rejestrów. Co nie znaczy że ich nie używa i kiedy w przerwaniu użyje rejestrów to zmieni ich wartości które są na pewno potrzebne innym procedurom.
Myślę że do takich zadań nie potrzeba Nosave, ale z ciekawości sprawdziłem i wygenerowałem też kod dla tych przerwań ;)
Deszcz: $asm PUSH R24 PUSH R26 PUSH R27 !in R24, sreg PUSH R24 $end asm If Deszcz_sensor = 0 Then Incr Deszcz_licznik ' Tuned with NoSave Tool $asm POP R24 !out sreg, r24 POP R27 POP R26 POP R24 $end asm Return Wiatr: $asm PUSH R24 PUSH R26 PUSH R27 !in R24, sreg PUSH R24 $end asm If Wiatr_sensor = 0 Then Incr Wiatr_licznik ' Tuned with NoSave Tool $asm POP R24 !out sreg, r24 POP R27 POP R26 POP R24 $end asm Return Jak widać w tych przerwaniach procesor używa R27, R26 i R24 więc jeśli przed wejściem w obsługe przerwania coś było zapisane w tych rejestrach to tutaj ich wartość by była zamazana i program prawdopodobnie by sie niedługo wysypał.
Nie używaj parametru Nosave jeśli nie masz NoSave Tool :D
Awatar użytkownika
pimowo
Posty: 392
Rejestracja: 28 maja 2016, 10:07

Re: BASCOM-zliczanie impulsów.

Post autor: pimowo » 29 maja 2016, 11:07

Czyli wychodzi, że zrobiłem niezły misz-masz :D
Kondensatory oczywiście mam, tutaj pokazałem tylko wycinek schematu. Kondensatory mam przy samym uC na pinach.

Nie jestem pewny czy teraz będzie OK, czy dobrze zrozumiałem, ale wyszło mi coś takiego: $regfile = "m328pdef.dat" $crystal = 11059200 $baud = 19200 Config Timer0 = Timer , Prescale = 1024 , Compare A = Disconnect , Compare B = Disconnect , Clear Timer = 1 Enable Compare0a : On Compare0a Int_10ms Nosave : Compare0a = 107 '10ms @11MHz 107 Dim 10ms As Byte , 100ms As Byte , 1s As Byte Dim Deszcz_licznik As Byte , Wiatr_licznik As Byte Dim Deszcz_ilosc As Byte , Wiatr_predkosc As Byte Config Portd.2 = Input : Portd.2 = 0 : Wiatr_sensor Alias Pind.2 Config Portd.3 = Input : Portd.3 = 0 : Deszcz_sensor Alias Pind.3 Config Int0 = Rising Enable Int0 : On Int0 Deszcz Nosave Config Int1 = Rising Enable Int1 : On Int1 Wiatr Nosave Deszcz_licznik = 0 Wiatr_licznik = 0 Enable Interrupts Print "START" Do If 10ms = 1 Then 10ms = 0 Incr 100ms End If If 100ms = 100 Then 100ms = 0 Incr 1s End If If 1s = 60 Then 1s = 0 Deszcz_ilosc = Deszcz_licznik Deszcz_licznik = 0 Wiatr_predkosc = Wiatr_licznik Wiatr_licznik = 0 Print Deszcz_ilosc ; " " ; Wiatr_predkosc End If Loop End Int_10ms: $asm PUSH R24 !in R24, sreg PUSH R24 $end Asm 10ms = 1 ' Tuned with NoSave Tool $asm POP R24 !out sreg, r24 POP R24 $end Asm Return Deszcz: $asm PUSH R24 PUSH R26 PUSH R27 !in R24, sreg PUSH R24 $end Asm If Deszcz_sensor = 0 Then Incr Deszcz_licznik ' Tuned with NoSave Tool $asm POP R24 !out sreg, r24 POP R27 POP R26 POP R24 $end Asm Return Wiatr: $asm PUSH R24 PUSH R26 PUSH R27 !in R24, sreg PUSH R24 $end Asm If Wiatr_sensor = 0 Then Incr Wiatr_licznik ' Tuned with NoSave Tool $asm POP R24 !out sreg, r24 POP R27 POP R26 POP R24 $end Asm Return ATmega zlicza sobie impulsy i wysyła po UART :D
Nie mam jeszcze sensorów które mają docelowo robić pomiary i robię sztuczne impulsy na zwykłym switchu.
Awatar użytkownika
niveasoft
Posty: 1216
Rejestracja: 17 sie 2015, 12:13
Kontakt:

Re: BASCOM-zliczanie impulsów.

Post autor: niveasoft » 29 maja 2016, 12:47

Tak sobie czasem rozważam różne opcje i tak na Twoim przykładzie.
Po co sprawdzać czy pin Wiatr lub Deszcz jest w stanie niskim skoro tylko taki stan może wywołać przerwanie i tylko mając stan niski może sie program tam znaleźć.
Wystarczy więc chyba tylko zwiększać licznik bo to że pin jest w stanie niskim to pewnik.

Co do tego odmierzania czasu to już tez myślałem nad tym.
Żeby inkrementować jakąś zmienną (Incr 100ms) to program musi ja załadowac do jakiegos rejestru, zwiększyć i zwolnić.
Później żeby sprawdzić czy nie jest większa od 100 znów musi ją załadować i porównać z wartością 100.
To trochę marnotrawstwo więć teraz zapisałbym to tak że sprawdzamy czy zmienna osiągnęła juz 100, jesli nie to ją zwiększamy, a jeśli tak to wykonujemy czynności jak przy 1s i dodatkowo zerujemy zmienną mając ją cały czas pod ręką w jednym i tym samym rejestrze ;)
Ot taka mini optymalizacja :P i nie chodzi mi o oszczędność tylko o inny tok myślenia :D
$regfile = "m328pdef.dat" $crystal = 11059200 $baud = 19200 Config Timer0 = Timer , Prescale = 1024 , Compare A = Disconnect , Compare B = Disconnect , Clear Timer = 1 Enable Compare0a : On Compare0a Int_10ms Nosave : Compare0a = 107 '10ms @11MHz 107 Dim 10ms As Byte , 100ms As Byte , 1s As Byte Dim Deszcz_licznik As Byte , Wiatr_licznik As Byte Config Portd.2 = Input : Portd.2 = 0 : Wiatr_sensor Alias Pind.2 Config Portd.3 = Input : Portd.3 = 0 : Deszcz_sensor Alias Pind.3 Config Int0 = Rising Enable Int0 : On Int0 Deszcz Config Int1 = Rising Enable Int1 : On Int1 Wiatr Deszcz_licznik = 0 Wiatr_licznik = 0 Enable Interrupts Print "START" Do If 10ms = 1 Then 10ms = 0 If 100ms < 99 Then Incr 100ms Else 'mamy 1s 100ms = 0 If 1s < 59 Then Incr 1s Else 'mamy 1min 1s = 0 Print Deszcz_licznik ; " " ; Wiatr_licznik Deszcz_licznik = 0 : Wiatr_licznik = 0 End If End If End If Loop End Int_10ms: $asm PUSH R24 !in R24, sreg PUSH R24 $end Asm 10ms = 1 ' Tuned with NoSave Tool $asm POP R24 !out sreg, r24 POP R24 $end Asm Return Deszcz: Incr Deszcz_licznik Return Wiatr: Incr Wiatr_licznik Return
Awatar użytkownika
pimowo
Posty: 392
Rejestracja: 28 maja 2016, 10:07

Re: BASCOM-zliczanie impulsów.

Post autor: pimowo » 29 maja 2016, 19:14

Kolego @niveasoft nie wiem jak Ty to robisz, ale Twoje wskazówki, programy działają idealnie i bezbłędnie ;)

Zanim ruszę dalej to chciałbym Cię podpytać czy masz pomysł jak posyłać dane poprzez ESP8266?

Wymyśliłem sobie, że dane które zbiera AVR prześlę po UART do ESP, a ten prześle je dalej po WiFi. Na Twojej stronie znalazłem, że bawiłeś się modułem ESP i rozwiązałeś to dużo ciekawiej bo AVR robi wszystko, a ESP jest wykorzystany jako most do wysyłania danych.

U mnie działa to tak:
- AVR robi pomiary/odczyty
- AVR włącza ESP (podaje napięcie na nogę CH_PD)
- AVR wysyła dane przez UART do ESP
- ESP odbiera dane
- ESP wysyła dane do Raspberry Pi z systemem NetTemp
- AVR wyłącza ESP

Jeżeli chodzi o kod dla ESP to mam coś takiego w LUA:
init.lua -- Konfiguracja WiFi wifi.setmode(wifi.STATION) wifi.sta.config("siec","haslo") wifi.sta.connect() -- Konfiguracja UART uart.setup(0,19200,8,0,1,0) GlownyProgram="avr.lua" -- Po uruchomieniu polacz z siecia WiFi tmr.alarm(0, 100, 1, function() if (wifi.sta.getip() == nil) then print("Lacze z WiFi...") else tmr.stop(0) print("Polaczony z WiFi *IP: ".. wifi.sta.getip() .."") print("Wykonywanie ".. GlownyProgram) dofile(GlownyProgram) end end) avr.lua -- Konfiguracja modulu pod NetTemp NettempIP="192.168.1.2" -- Tutaj wpisujemy IP NetTemp NettempKey="123456" -- Ustawiamy w Settings -> ServerNode -> Key SensorIP="192.168.1.233" -- IP naszego modulu -- Posylamy dane function SendData() conn=net.createConnection(net.TCP, 0) conn:connect(80,NettempIP) -- dana 1 conn:send("GET /receiver.php?key=" .. NettempKey .. "&type=" .. "humi" .. "&value=" .. uCData01 .. "&ip=" .. SensorIp .. "&device=" .. "wireless" .. " HTTP/1.1\r\nHost: NettempIP\r\n" .."Connection: keep-alive\r\nAccept: */*\r\n\r\n") -- dana 2 conn:send("GET /receiver.php?key=" .. NettempKey .. "&type=" .. "temp" .. "&value=" .. uCData02 .. "&ip=" .. SensorIp .. "&device=" .. "wireless" .. " HTTP/1.1\r\nHost: NettempIP\r\n" .."Connection: keep-alive\r\nAccept: */*\r\n\r\n") -- dana 3 conn:send("GET /receiver.php?key=" .. NettempKey .. "&type=" .. "vcc" .. "&value=" .. uCData03 .. "&ip=" .. SensorIp .. "&device=" .. "wireless" .. " HTTP/1.1\r\nHost: NettempIP\r\n" .."Connection: keep-alive\r\nAccept: */*\r\n\r\n") conn:on("receive", function(conn, payload) end ) end -- Odbierz dane z UART uart.on("data", "\r", function(data) uCData01=string.sub(data, 1, 4) uCData02=string.sub(data, 6, 7) uCData03=string.sub(data, 9, 12) SendData() end, 0) W sumie mi to działa, ale jest jedna, wielka niedogodność. Dane muszą mieć jednakową długość, a jak wiemy dane np. temperatury mają różne wartości i wszystko się rozjeżdża :(
Docelowo będzie 15 różnych danych do wysłania z AVR
ODPOWIEDZ