What do rabbits, buttons and lean management have to do with the Raspberry Pi? Find out in this article.
Everything started with the arrival of 2 rabbits in our garage. The children were fully motivated and the feeding and cleaning was ensured. But as sometimes happens, the feeding frequency by the kids didn’t quite fit the wishes of the rabbits. So a solution had to be found.
The first solution was: Daddy does everything alone. I didn’t like that so well. So I needed a second.
At the job I would tackle it with lean management methods. Visualize the process, eliminate waste, try it, improve it etc.
That was a good plan. So we convened the Family Council and then we started together.
The result was really impressive. My daughter made a slide card and there were rules.
Rules (= "process flow")
1. The sliding card is taped to the front door and noticed.
2. Every morning Dad has to slide the card to “hungry”.
3. As soon as someone feeds the rabbits, he sets the card to “had enough”.
4. In the evening it will be checked: had the rabbits eaten enough?
If yes, everything is fine. If no, then someone has to get out again.
So far so good. It worked pretty well for a while. But there were times the slide card wasn't checked every evening. And for the cleaning of the enclosure, there was the same problem.
It was clear: → Continuous improvement! A third solution must come.
The solution had to be smarter in any case, also to arouse the interest again. And it should solve all the problems this time:
- It has to be clear to everyone whether they have already been fed.
- The "cleaning" problem must also be solved.
- If something is forgotten, a memory must come.
- And the most important thing: it has to be fun.
With my son, I then considered a realization concept: our smart home, consisting of a Raspberry Pi, is being expanded; for rabbits, 3 buttons are installed:
(3) For treats
The Raspberry is running a Python program to monitor key events. If keys are pressed, event processing takes place: the respective counter is reset for the selected period:
- Fed: daily counter (must be done daily until 19:00h)
- Cleaned: weekly counter (must be done til Sunday 12:00h) → If there is no reset by the chosen time, an email will be sent with a reminder to all children.
For each event, a text file is created, which can also be evaluated by the web server
The keys were built right next to the stable. On a small wooden box, the 3 keys stand out easily. Which buttons you use does not matter. I like the industrial versions better.
Often you get good used push button / switch offers on eBay if you search under "industrial push button". The buttons are very robust. And it is very easy to install an LED (a little hot glue is enough), thus the lighting problem can be solved elegantly.
The panel we have christened Rabbit Console.
The circuit design of the push buttons takes place via a 10kΩ pull-up resistor against the 3.3V of the Raspberry. Since there are often problems with long lines, I refer to my project Telekom T-Concept X311 with Doorline on Raspberry. There I described different solutions. As you will see later, we use a software solution here. Follow the attached schematic below.
First, it must be clear what the function of the buttons and LEDs should look like. The LEDs should definitely not be permanently switched on (and possibly disturb the rabbits in the dark).
In order to still recognize the current status, we have considered to display the status after the first key stroke.
→ Rabbits have not yet been fed: LED flashes for 10 seconds
→ Rabbits have already been fed: LED lights up for 10 seconds
If the button is pressed again within 10 seconds, this is considered as a signal for feeding.
Programming is best done via a test setup. We used a breadboard and our Raspberry plug.
The structure of the buttons is identical for all 3, so it is defined by its own class:
class EreignisTaster: def __init__(self,PinTaster,PinLed,Name,DateinameProtokoll,DateinameStatus): self.PinTaster=PinTaster self.PinLed=PinLed self.Name=Name self.DateinameProtokoll=DateinameProtokoll self.DateinameStatus=DateinameStatus self.Status=False self.gedrueckt=0 self.lastKeypress=0 self.PruefungIntervall="-" self.PruefungErfolgt=0 self.Meldung=""
The function to check if a button has been pressed looks like this:
def Pruefung(self): if GPIO.input(self.PinTaster)==False: if self.gedrueckt==0: #key is pressed self.gedrueckt=1 self.lastKeypress=datetime.datetime.now() print("Key "+self.Name+": recognized") else: if (self.gedrueckt==1) and (datetime.datetime.now()-self.lastKeypress>datetime.timedelta(milliseconds=200)): #show state print("Key "+self.Name+": show state") self.lastKeypress=datetime.datetime.now() self.gedrueckt=2 #LED on GPIO.output(self.PinLed,True) if (self.gedrueckt==2) and (datetime.datetime.now()-self.lastKeypress>datetime.timedelta(milliseconds=1000)): print("Key "+self.Name+": event recognized") Blink(self.PinLed,0.1) self.Status=True GPIO.output(self.PinLed,True) KaninchenLogEintrag(self.Name) #second log, maybe for a webserver tex=open(pfadDokumente+self.DateinameProtokoll,'a') tex.write('\n'+time.strftime('%d.%m.%Y %H:%M:%S')) tex.close() #write timestamp tex=open(pfadDokumente+self.DateinameStatus,'w') tex.write(time.strftime('%d.%m.%Y %H:%M:%S')) tex.close() self.lastKeypress=datetime.datetime.now()
A flag is used to check whether the events have already occurred. If this is not the case, a reminder will be sent.
This is how the source code for daily feeding looks no later than 19:00. Definitions of intervals are checked.
#definitions Taster=[0,1,2] Taster=EreignisTaster(12,22,"Feeded","kaninchen_gefuettert.txt","kaninchen_gefuettert2.txt") Taster=EreignisTaster(16, 9,"For treats","kaninchen_leckerli.txt","kaninchen_leckerli2.txt") Taster=EreignisTaster(20,11,"Cleaned","kaninchen_saubergemacht.txt","kaninchen_saubergemacht2.txt") Taster.PruefungIntervall="*-15:18" Taster.Meldung="It is later than 19:00 and the rabbits weren't feeded." #Enter number for weekday for weekly or * for daily #0: Sunday #1: Monday #... #6: Saturday Taster.PruefungIntervall="0-12:00" Taster.Meldung="It is Sunday and later than 12:00 and the rabbits stable wasn't cleaned."
The actual test takes place here:
try: while True: for t in Taster: t.Pruefung() t.StatusZeigen(tick) time.sleep(0.2) tick=tick+1 if tick>300: #Check every minute: are reminders necessary? tick=0 s=time.strftime("%Y.%m.%d") #reset the counter at 23:59 if s!=signal0h: if time.strftime("%H:%M")=="23:59": signal0h=s for t in Taster: if t.PruefungIntervall!="-": if t.PruefungIntervall=="*": #if daily interval, then reset t.Status=False t.PruefungErfolgt="-" print("Daily reset: "+t.Name) else: #if weekly, then check if day fits if time.strftime("%w")==t.PruefungIntervall: t.Status=False t.PruefungErfolgt="-" print("Daily reset: "+t.Name) #Check if reminder is necessary? for t in Taster: if t.PruefungIntervall!="-": if s!=t.PruefungErfolgt: if ((t.PruefungIntervall=="*") and (time.strftime("%H:%M")==t.PruefungIntervall[2:])) or (time.strftime("%w-%H:%M")==t.PruefungIntervall): #it is the first time of the check t.PruefungErfolgt="X" #because of this, there's no further check if t.Status==False: #MailVersenden('Thomas Angielsky <email@example.com>','Hinweis',t.Meldung) print(t.Meldung)
In the mail program, the result could look like this:
So far so good. How well or interestingly this solution worked in practice with my kids, you'll read maybe later in another article...
Wenn Sie diesen Artikel in Deutsch lesen möchten, schauen Sie doch in meinen Blog techpluscode.de.