Bascom - zavlahový automat

Robím si závlahový automat a zastavil som sa na tom najdôležitejšom a to nastavenie automatickej závlahy. Nastavenie hodín som ako tak zvládol, ale teraz by som potreboval nakopnúť. Idea je taká, že automat bude mať 8 okruhov a každý okruh bude mať možnosť nastaviť 4 rôzne štartovacie časy. Dĺžka závlahy by sa dala nastaviť napríklad na 2 hodiny. Ďalej by tam boli tri rôzne programy napr. A, B a C to znamená, že v každom programe môžu byť tie okruhy inak nastavené. Problém je v tom, že neviem ako alebo do čoho ukladať tie nastavené hodnoty.

predstavujem si to takto:

automatA1 - nejaká premenná programu A a okruhu 1 a tá obsahuje tieto údaje:

13:00 - štartovací čas 1.
00:30 - dĺžka závlahy 1.
14:00 - štartovací čas 2.
00:15 - dĺžka závlahy 2.
15:00 - štartovací čas 3.
00:30 - dĺžka závlahy 3.
17:00 - štartovací čas 4.
00:30 - dĺžka závlahy 4.
P - závlaha v pondelok
U - závlaha v utorok
.
.
.
N - závlaha v nedelu

a ďalšia premenná automatA2 - premenná programu A a okruhu 2 atď.

Pomôže niekto ?

Tu je pre istotu môj nedokončený program:

[code]$regfile = “m32def.dat”
$crystal = 8000000
$hwstack = 40
$swstack = 16
$framesize = 32
$lib “glcdKS108.lbx”
$lib “mcsbyte.lbx”

Config Graphlcd = 128 * 64sed , Dataport = Portc , Controlport = Portd , Ce = 2 , Ce2 = 3 , Cd = 4 , Rd = 5 , Reset = 7 , Enable = 6

Config Scl = Portb.0
Config Sda = Portb.1
Config I2cdelay = 5

Dim Year As Byte
Dim Month As Byte
Dim Day As Byte
Dim Weekday As Byte
Dim Hours As Byte
Dim Minutes As Byte
Dim Seconds As Byte
Dim S_hours As String * 2
Dim S_year As String * 3
Dim S_minutes As String * 2
Dim S_seconds As String * 2
Dim Read_time As Bit

Dim Hours_sett As Byte
Dim Minutes_sett As Byte
Dim Seconds_sett As Byte
Dim Weekday_sett As Byte

Dim Hodiny As Byte
Dim Minuty As Byte
Dim S_hodiny As String * 2
Dim S_minuty As String * 2
Dim Dnivtyzdni As Byte

Dim A As Byte
Dim Back As Integer

Dim Mainmenu(4) As String * 13
Dim Settmenu(4) As String * 15
Dim Dni(7) As String * 8
Dim Inverse As Byte
Dim Main_selec As Byte
Dim Sett_selec As Byte
Dim Sett_automat As Byte
Dim Sett_hod As Byte

Dim Program(3) As String * 1
Dim Sett_program As Byte
Dim Starttime(4) As Byte
Dim Okruh_sett(8) As Byte
Dim Okruh As Byte

Declare Sub Identification

Config Pina.0 = Input : Pina.0 = 1
Config Pina.3 = Input : Pina.3 = 1
Config Pina.4 = Input : Pina.4 = 1

Up_tl Alias Pina.3
Down_tl Alias Pina.0
Go_tl Alias Pina.4

Config Debounce = 30

Read_time = 0
Inverse = 0

Program(1) = “A”
Program(2) = “B”
Program(3) = “C”

Okruh_sett(1) = 1
Okruh_sett(2) = 2
Okruh_sett(3) = 3
Okruh_sett(4) = 4
Okruh_sett(5) = 5
Okruh_sett(6) = 6
Okruh_sett(7) = 7
Okruh_sett(8) = 8

Mainmenu(1) = “Nastavenie”
Mainmenu(2) = “Ovladanie”
Mainmenu(3) = “Identifikacia”
Mainmenu(4) = “Exit”

Settmenu(1) = “Hodiny/den”
Settmenu(2) = “Automat/zavlaha”
Settmenu(3) = “Snimac”
Settmenu(4) = “Exit”

Dni(1) = “Pondelok”
Dni(2) = "Utorok "
Dni(3) = "Streda "
Dni(4) = "Stvrtok "
Dni(5) = "Piatok "
Dni(6) = "Sobota "
Dni(7) = "Nedela "

Config Timer1 = Timer , Prescale = 8

On Timer1 Readtime
Enable Interrupts
Enable Timer1

Start Timer1
'--------------------------------Start------------------------------------------
Start_menu:

Back = 0
Main_selec = 1

Cls

Do

If Read_time = 1 Then
Read_time = 0
Setfont Font16x16
Lcdat 1 , 50 , S_hours ; “:” ; S_minutes
Setfont My6_8
Lcdat 7 , 1 , " 1 2 3 4 5 6 7"

Select Case Weekday
Case 1 : Lcdat 8 , 7 , “-” , 0 : Lcdat 8 , 115 , " " , 0
Case 2 : Lcdat 8 , 25 , “-” , 0 : Lcdat 8 , 7 , " " , 0
Case 3 : Lcdat 8 , 43 , “-” , 0 : Lcdat 8 , 25 , " " , 0
Case 4 : Lcdat 8 , 61 , “-” , 0 : Lcdat 8 , 43 , " " , 0
Case 5 : Lcdat 8 , 79 , “-” , 0 : Lcdat 8 , 61 , " " , 0
Case 6 : Lcdat 8 , 97 , “-” , 0 : Lcdat 8 , 79 , " " , 0
Case 7 : Lcdat 8 , 115 , “-” , 0 : Lcdat 8 , 97 , " " , 0
End Select

Showpic 6 , 39 , Triska
Showpic 24 , 39 , Triska
Debounce Go_tl , 0 , Main_menu
End If

Loop
'--------------------------------Hlavne menu------------------------------------
Main_menu:

Cls

Do

Setfont Font8x8

Lcdat 1 , 1 , " -Hlavne menu-" , 0

If Main_selec = 1 Then
Inverse = 1
End If
Lcdat 3 , 1 , Mainmenu(1) , Inverse
Inverse = 0

If Main_selec = 2 Then
Inverse = 1
End If
Lcdat 4 , 1 , Mainmenu(2) , Inverse
Inverse = 0

If Main_selec = 3 Then
Inverse = 1
End If
Lcdat 5 , 1 , Mainmenu(3) , Inverse
Inverse = 0

If Main_selec = 4 Then
Inverse = 1
End If
Lcdat 6 , 1 , Mainmenu(4) , Inverse
Inverse = 0

Debounce Up_tl , 0 , Inc_main , Sub
Debounce Down_tl , 0 , Dec_main , Sub
Debounce Go_tl , 0 , Go_main , Sub

Incr Back

If Back = 1000 Then
Goto Start_menu
End If

Loop

Inc_main:

Back = 0
If Main_selec <= 3 Then
Main_selec = Main_selec + 1
End If

Return

Dec_main:

Back = 0
If Main_selec >= 2 Then
Main_selec = Main_selec - 1
End If

Return

Go_main:

Back = 0
If Main_selec = 1 Then
Gosub Setting_menu
End If

If Main_selec = 2 Then
'Call xxx_sub
End If

If Main_selec = 3 Then
Call Identification
End If

If Main_selec = 4 Then
Goto Start_menu
End If

Return
'-------------------------------Identifikacia-----------------------------------
Sub Identification:

Cls
Lcdat 1 , 1 , "-Identifikacia-" , 0
Lcdat 4 , 1 , " Automat-808/1  " , 0
Lcdat 6 , 1 , "  S/N: 130105  " , 0
Wait 5
Cls

End Sub
'-------------------------------Menu nastavenie---------------------------------

Setting_menu:

Cls

Sett_selec = 1

Do

Setfont Font8x8
Lcdat 1 , 1 , " -Nastavenie-" , 0

If Sett_selec = 1 Then
Inverse = 1
End If
Lcdat 3 , 1 , Settmenu(1) , Inverse
Inverse = 0

If Sett_selec = 2 Then
Inverse = 1
End If
Lcdat 4 , 1 , Settmenu(2) , Inverse
Inverse = 0

If Sett_selec = 3 Then
Inverse = 1
End If
Lcdat 5 , 1 , Settmenu(3) , Inverse
Inverse = 0

If Sett_selec = 4 Then
Inverse = 1
End If
Lcdat 6 , 1 , Settmenu(4) , Inverse
Inverse = 0

Debounce Up_tl , 0 , Inc_sett , Sub
Debounce Down_tl , 0 , Dec_sett , Sub
Debounce Go_tl , 0 , Go_sett , Sub

Incr Back

If Back = 1000 Then
Goto Start_menu
End If

Loop

Return

Inc_sett:

Back = 0
If Sett_selec <= 3 Then
Sett_selec = Sett_selec + 1
End If

Return

Dec_sett:

Back = 0
If Sett_selec >= 2 Then
Sett_selec = Sett_selec - 1
End If

Return

Go_sett:

Back = 0
If Sett_selec = 1 Then
Gosub Sett_time
End If

If Sett_selec = 2 Then
Goto Automat
End If

If Sett_selec = 3 Then
Call Identification
End If

If Sett_selec = 4 Then
Goto Main_menu
End If

Return

'-------------------------------Nastavenie hodin--------------------------------

Sett_time:

Sett_hod = 1

Cls

S_hodiny = S_hours
S_minuty = S_minutes
Dnivtyzdni = Weekday

Do

Setfont Font8x8
Lcdat 1 , 1 , " -Hodiny/dni-" , 0

If Sett_hod = 1 Then
Inverse = 1
End If
Lcdat 3 , 44 , S_hodiny , Inverse
Inverse = 0

Lcdat 3 , 60 , “:” , 0

If Sett_hod = 2 Then
Inverse = 1
End If
Lcdat 3 , 68 , S_minuty , Inverse
Inverse = 0

If Sett_hod = 3 Then
Inverse = 1
End If
Lcdat 5 , 44 , Dni(dnivtyzdni) , Inverse
Inverse = 0

If Sett_hod = 4 Then
Inverse = 1
End If
Lcdat 8 , 1 , “Zrusit” , Inverse
Inverse = 0

If Sett_hod = 5 Then
Inverse = 1
End If
Lcdat 8 , 81 , “Ulozit” , Inverse
Inverse = 0

Hodiny = Val(s_hodiny)
Minuty = Val(s_minuty)

Debounce Up_tl , 0 , Inc_time , Sub
Debounce Down_tl , 0 , Dec_time , Sub
Debounce Go_tl , 0 , Go_time , Sub

Loop

Dec_time:

If Sett_hod <= 4 Then
Sett_hod = Sett_hod + 1
End If

Return

Inc_time:

If Sett_hod >= 2 Then
  Sett_hod = Sett_hod - 1
End If

Return

Go_time:

If Sett_hod = 1 Then
Hodiny = Hodiny + 1
  If Hodiny = 24 Then
  Hodiny = 0
  End If
End If

S_hodiny = Str(hodiny)
S_hodiny = Format(s_hodiny , “00”)

If Sett_hod = 2 Then
Minuty = Minuty + 1
If Minuty = 60 Then
Minuty = 0
End If
End If

S_minuty = Str(minuty)
S_minuty = Format(s_minuty , “00”)

If Sett_hod = 3 Then
Dnivtyzdni = Dnivtyzdni + 1
If Dnivtyzdni = 8 Then
Dnivtyzdni = 1
End If
End If

If Sett_hod = 4 Then
Goto Setting_menu
End If

If Sett_hod = 5 Then
Goto Writetime
End If

Return

'-------------------------------Citanie hodin=----------------------------------
Readtime:

I2cstart
I2cwbyte &B11010000
I2cwbyte 0
I2cstop
'Waitms 50
I2cstart
I2cwbyte &B11010001
I2crbyte Seconds , Ack
I2crbyte Minutes , Ack
I2crbyte Hours , Ack
I2crbyte Weekday , Ack
I2crbyte Day , Ack
I2crbyte Month , Ack
I2crbyte Year , Nack
Seconds = Makedec(seconds)
Minutes = Makedec(minutes)
Hours = Makedec(hours)
Weekday = Makedec(weekday)
Day = Makedec(day)
Month = Makedec(month)
Year = Makedec(year)
I2cstop
S_hours = Str(hours)
S_hours = Format(s_hours , “00”)
S_year = Str(year)
S_year = Format(s_year , “000”)
S_minutes = Str(minutes)
S_minutes = Format(s_minutes , “00”)
S_seconds = Str(seconds)
S_seconds = Format(s_seconds , “00”)
Read_time = 1

Return

'-------------------------------Zapis hodin=----------------------------------
Writetime:

Seconds_sett = Makebcd(0) : Minutes_sett = Makebcd(minuty) : Hours_sett = Makebcd(hodiny) : Weekday_sett = Makebcd(dnivtyzdni)
I2cstart
I2cwbyte &B11010000
I2cwbyte 0
I2cwbyte Seconds_sett
I2cwbyte Minutes_sett
I2cwbyte Hours_sett
I2cwbyte Weekday_sett
I2cstop

Cls

Setfont Font8x8
For A = 0 To 4
Lcdat 4 , 24 , “Ukladam…” , 0
Waitms 500
Lcdat 4 , 24 , " " , 0
Waitms 500
Next A
Goto Setting_menu

Return

'------------------------------Automat------------------------------------------

Automat:

Cls

Okruh = 1
Sett_automat = 1
Sett_program = 1

Do
Restore Data1

Setfont Font8x8
Lcdat 1 , 1 , " -Nast. automat-" , 0
Setfont Font16x16
If Sett_automat = 1 Then
Inverse = 1
End If
Lcdat 3 , 1 , Program(sett_program) , Inverse
Inverse = 0

Lcdat 3 , 17 , “-” , 0

If Sett_automat = 2 Then
Inverse = 1
End If
Lcdat 3 , 33 , Okruh_sett(okruh) , Inverse
Inverse = 0

Loop

Return

End

$include “font8x8.font”
$include “my6_8.font”
$include “font16x16.font”
$include “my12_16.font”

Triska:

$bgf “Triska.bgf”[/code]

Nejjednodušší se mě jeví EEPROM. Ale záleží jaký Atmel používáš, aby se tam všechny data vešly.

Používá Atmega 32 a ta má 1kB vnitřní EEprom. Kdyby nestačila tak se dá použít externí paměť EEprom.

Jasné. Plánujem potom použiť externú EEprom, ale potrebujem pomôcť ako to do nejakej premennej uložím. Skrátka nechcel by som mať 300 premenných ale napríklad tak ako som písal, že jedna premenná by obsahovala 4 štartovacie časy, 4 doby trvania závlahy atď. Neviem či som sa zrozumiteľne vyjadril. Potrebujem trochu nakopnúť.

NO inak to nepojde par bajtov tej eeprom to zaberie.

Do vnitžní eeprom v Atmega uložíš teoreticky 1024 proměnných - to ti nestačí?

To samozrejme stačí. Pokiaľ sa nemýlim, tak EEPROM je možné 100 000 krát čítať a zapisovať. Počíta sa do toho aj keď číta EEPROM samotný program MCU ?

Čtení je neomezené, pouze počet zápisů/mazání je omezený. Nerozlišuje se zda zapisuje MCU nebo programovadlo.

Omezený počet zápisů má i externí EEPROMka. V tomhle směru jsou výhodnější paměti FRAM. Spojují výhody SRAM a EEPROM. Mají neomezený počet zápisů, rychlost jako SRAM a přitom fungují jako EEPROM. Vyrábí se i kompatibilní s I2C nebo SPI EEPROMkama. A ani cenově už nejsou nedostupné. Viz tme.eu/cz/katalog/?idp=1&search=fram&cleanParameters=1#id_category=100424&page=1&s_field=artykul&s_order=ASC a tady máš odkaz na datasheet : tme.eu/cz/Document/ff873844b613a33b81b47fb60bf83a45/fm25l256b.pdf. Ten má 32768 bytů a je za nějakých 142 Kč vč. DPH - SPI.

Tazateli bude pro jeho účel stačit interní EEPROM jistě bohatě.

To zajisté, ale proč tajit i další možnosti - třeba pro případ budoucího použití.

To jo. Ceny FRAM jsou už docela lidské a i trvanlivost dat 45 let je docela zajímavá (dřívější SRAM vydržely jen pár let a byly dost rozměrné, kvůli integrované baterce).

Ďakujem za nápady. FRAM ešte nepoznám, tak si jednu kúpim a budem testovať. Pravdepodobne v tomto projekte využijem internú EEPROM. Mám predsa ešte jednu otázku. Uvediem príklad: V prípade, že by som oficiálne predával tento výrobok, tak bolo by to fér voči zákazníkovi používať internú EEPROM keď vieme, že má obmedzený počet zápisov ? 100 000 je samozrejme veľa, ale predsa to obmedzenie tam je a takmer všetci o tom vedia.

Prodejce musí uvést za co se zaručuje a spočítat např. životnost. Jestli dobře chápu, tak do EEPROM se bude ukládat konfigurace nastavená uživatelem a obsah EEPROM se pak už nebude měnit (až do příští změny provedené uživatelem), takže lze předpokládat za dobu životnosti výrobku jen desítky až stovky zápisů, což by neměl být problém.

Pokud si program ukládá nějakou konfiguraci sám, musí se program zefektivnit tak, aby limitního počtu zápisů nemohl dosáhnout - tj. při zápisu kontrolovat starý obsah, zda se mění, aby se zápis provedl jen při změně bajtu. Zápisy dělat jen v nutných případech - např. ukládat automatickou konfiguraci jen s nějakým minimálním intervalem nebo pomocí přerušení při signalizaci výpadku napájení. Jistě by byla velká chyba měnit nějaká data v EEPROM např. každou sekundu. Když už je opravdu nutné ukládat nějakou buňku příliš často, pak lze zápisy zřetězit - ukládat záznamy za sebou s časovou značkou, při čtení najít poslední záznam, tím se dá počet zápisů trochu zvýšit.

O nesolidnost k zákazníkovi se ani jednat nemůže - pokud bude výrobek špatně navržený a zápisy se vyčerpají v záruční době, je to na triko výrobce a musí výrobek vyměnit.

Ok. Super. Je mi to jasné. Ďakujem