Our house cat Toto has been getting a bit chubby lately, after having him sterilized I started reading up on an ideal diet for a cat his age (he is 9 months old).
Toto stays in the living room and wakes up early, super hungry. If he doesn't get his fix, there will be biting.
Before building an automated cat feeder, to get an idea about what's available in the market, a simple google search showed pet feeders were selling for around 327TL - 850TL (80$ - 200$). None of the regular ones offered voice activation.
After hearing about the Alexa Arduino challenge I decided to come up with a way to automate Toto's meals and learn Alexa in the process.
The main idea was to use sensors and voice as inputs and release some food that's kept in a container to Toto's food bowl.
I wanted to keep this simple so it can be finished in a reasonable amount of time and I knew I would have problems with mechanic side of things. Another thing main point was to use what I had available, so it became a 4 part plan:
1. Device1.1 Arduino Software
Set up Arduino with bluefruit (comes with an open source android app)
I extended bluefruit's LE friend (Adafruit_BluefruitLE_nRF51) library's UART communication example to receive 3 types of commands:
- releaseinterval:t1 -> where t1 is the duration of the food release.
- feedinterval:t2 -> where t2 is the duration between meals.
- release_latch -> release food immediately.
Also had to add a few tricks to shake the box, because sometimes food would get stuck on the way.
void feedTotoLoop(int x) {
for(int i = 0; i < x; i++) {
digitalWrite(13, HIGH);
delay(100);
digitalWrite(13, LOW);
delay(100);
digitalWrite(13, HIGH);
delay(100);
digitalWrite(13, LOW);
delay(100);
}
}
1.2 Circuit
I wanted to use the Large Push-Pull Solenoid I have so I simply set it up as shown in the schematic.
2 x 9V batteries to power the solenoid and arduino can work from any usb adapter.
2. MechanicsIdea is to use solenoid as the latch to release food.
Simply cut a hole on the side of a pringles can and padded the inside so things would flow to the opening.
When solenoid is pulled and latch is opened, food drops to the food bowl.
I went all McGywer on this and I do regret it but it got the job done.
This took me an embarrassing amount of time. Luckily there is a lot of room to grow here. Next version can be rebuilt with a measuring cup and a better funnel.
3. AlexaAlexa can simply parse the voice command and return the value to the Android App. This is not the best use of Alexa's capabilities but I found it was a cool way to learn.
Following the Alexa Voice Services and Alexa Skills Kit documentation, I created a custom skill called: "Feed Toto" this skill listens to the following sample utterances:
"feedduration" is of type AMAZON.DURATION that is compatible with ISO 8601 which is supported by moment.js.
So if user is trying to schedule regular meals and "feedduration" is heard by Alexa, data is sent to Lambda inside the intent and can be recalled in the lambda function as below:
var intent = this.event.request.intent.name;
var durationValue = isSlotValidDuration(this.event.request, "feedduration");
// var slotvalue = request.intent.slots[slotName].value;
console.log("feedduration: " + durationValue);
var duration = moment.duration(durationValue);
console.log("parsed duration: " + duration); // correct!
var hourDuration = moment.duration(durationValue).hours();
var minuteDuration = moment.duration(durationValue).minutes();
var secondDuration = moment.duration(durationValue).seconds();
4. Mobile App4.1 Send triggers to Arduino over Bluetooth LE
Again, I cloned Adafruit's Bluefruit communication app and created my own activity for sending the pre-defined commands expected by the Arduino device software.
For UI, keep it as simple and obvious. 2 sliders and 3 buttons.
Feed Size in seconds shows how long the feeder will work to release food. I found out recommended feeding values for a cat (>6kg) is max 95 gram per day. (remember to check with your vet before over/under feeding your pet ;))
For my setup, this calls for a 10 second release which I call a regular meal.
1 second -> quick treat
5 seconds -> small meal
20 seconds -> for a feast
Feed Interval is in minutes. For testing you can set it to 1 per minute but I expect to use 6,8 or 12 hour intervals.
Once sliders are set, user can tap "SYNC" to send values and trigger an instant feed starting the schedule.
User can tap "FEED NOW" to release a treat (1 release interval).
User can tap "STOP" to stop the release if food bowl is overflowing. This will also clear any scheduled meals.
4.2 Connect up Alexa so it's possible to use voice as input
Alexa does not offer a direct Android library but there's a great open source library by willblaschko that abstracts Alexa API and makes it available to use.
I added 3 buttons for Alexa use and 1 text output on UI.
LOGIN: Required to login to amazon and allow "Feed Toto" custom skill to be used via the app.
LOGOUT: Logout.
ALEXA: When this button is clicked, a voice recorder is started. Recording is sent and processed as below.
Android App --> Amazon --> Alexa Intent --> Alexa Lambda Function --> [some workaround I implemented so I can read back the resuls] --> Android App
Now the "custom" field in the UI will be populated and the value spoken by the user will be send to Arduino to be set as the new regular meal schedule interval.
A simple example from the Amazon console Service Simulator:
-> Utterance:
feed toto every 2 hours
-> Service Request
Service Request
{
"session": {
"new": true,
...
}
},
"request": {
"type": "IntentRequest",
"requestId": "EdwRequestId.ccb19e46-4257-4afa-90e3-ce653e7ba8ae",
"intent": {
"name": "feedtoto",
"slots": {
"feedduration": {
"name": "feedduration",
"value": "PT2H"
}
}
},
"locale": "en-US",
"timestamp": "2018-01-04T16:01:10Z"
},
... },
"version": "1.0"
}
-> Service Response
{
"version": "1.0",
"response": {
"outputSpeech": {
"ssml": "<speak> OK. Toto will be fed every 2 hours </speak>",
"type": "SSML"
},
"card": {
"content": "feedinterval:7200",
"title": "Feed Toto"
},
"speechletResponse": {
"outputSpeech": {
"ssml": "<speak> OK. Toto will be fed every 2 hours </speak>"
},
"card": {
"content": "feedinterval:7200",
"title": "Feed Toto"
},
"shouldEndSession": true
}
},
"sessionAttributes": {}
}
5. OutroFinal operation looks like this:
"Alexa feed Toto" does what I set out to do. Surely there are a lot of areas for improvements. As always, I kept a list of possible future ideas:
- 3D print a standard 2L container with funnel, solenoid placement and release latch.
- Introduce a new activity in Android App to get the name, picture, age of cat and recommend meals automatically.
- Include a water fountain that can be used the same way. Cats prefer flowing water to still.
- A touch sensor that Toto can push to trigger the meal but I think this might be abused.
Let me know if you have comments and suggestions,
Thanks for reading,
Comments