├── LICENSE ├── README.md ├── server.py ├── static ├── assets │ ├── css │ │ └── main.css │ └── js │ │ └── main.js └── images │ └── favicon.png └── templates └── index.html /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Victor Ribeiro 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # raspberryCar 2 | 3 | A raspberry pi on wheels. See it working below. 4 | 5 | [](http://www.youtube.com/watch?v=4IDLDofuuLc) 6 | 7 | ## About 8 | 9 | This is my first real experiment with robotics. I've ordered the arduino car kit on the internet, but some parts went missing. 10 | So, instead of a arduino, I've used my raspberry pi to control the wheels. 11 | I wrote a simple flask server to expose the commands (go left, right, forward and backward) over the internet, that could be accessed by any device. 12 | Later I decided to use [myChatBot](https://github.com/victorqribeiro/myChatBot) to control the car. 13 | 14 | ## Brag 15 | 16 | This project was featured on HACKADAY - [Control Anything With a Chat Bot](https://hackaday.com/2019/01/05/control-anything-with-a-chat-bot). 17 | 18 | ## Warning 19 | 20 | You might have to add the address of the server as a trusted site, If you want to use the voice control without a SSL certificate. 21 | -------------------------------------------------------------------------------- /server.py: -------------------------------------------------------------------------------- 1 | 2 | from flask import Flask, render_template,request,redirect,url_for 3 | import RPi.GPIO as GPIO 4 | from time import sleep 5 | 6 | GPIO.setmode(GPIO.BCM) 7 | GPIO.setwarnings(False) 8 | 9 | #motor A 10 | GPIO.setup(17, GPIO.OUT) 11 | GPIO.setup(27, GPIO.OUT) 12 | 13 | #motor B 14 | GPIO.setup(23, GPIO.OUT) 15 | GPIO.setup(24, GPIO.OUT) 16 | 17 | app = Flask(__name__) 18 | title = "RaspberryCar" 19 | heading = "ToDo Reminder" 20 | 21 | @app.route("/") 22 | def tasks(): 23 | return render_template('index.html') 24 | 25 | @app.route("/forward") 26 | def forward(): 27 | GPIO.output(17, GPIO.HIGH) 28 | GPIO.output(27, GPIO.LOW) 29 | GPIO.output(23, GPIO.HIGH) 30 | GPIO.output(24, GPIO.LOW) 31 | sleep(1) 32 | GPIO.output(17, GPIO.LOW) 33 | GPIO.output(27, GPIO.LOW) 34 | GPIO.output(23, GPIO.LOW) 35 | GPIO.output(24, GPIO.LOW) 36 | return redirect("/") 37 | 38 | @app.route("/backwards") 39 | @app.route("/backward") 40 | def backward(): 41 | GPIO.output(17, GPIO.LOW) 42 | GPIO.output(27, GPIO.HIGH) 43 | GPIO.output(23, GPIO.LOW) 44 | GPIO.output(24, GPIO.HIGH) 45 | sleep(1) 46 | GPIO.output(17, GPIO.LOW) 47 | GPIO.output(27, GPIO.LOW) 48 | GPIO.output(23, GPIO.LOW) 49 | GPIO.output(24, GPIO.LOW) 50 | return redirect("/") 51 | 52 | @app.route("/left") 53 | def left(): 54 | GPIO.output(17, GPIO.LOW) 55 | GPIO.output(27, GPIO.HIGH) 56 | GPIO.output(23, GPIO.HIGH) 57 | GPIO.output(24, GPIO.LOW) 58 | sleep(1) 59 | GPIO.output(17, GPIO.LOW) 60 | GPIO.output(27, GPIO.LOW) 61 | GPIO.output(23, GPIO.LOW) 62 | GPIO.output(24, GPIO.LOW) 63 | return redirect("/") 64 | 65 | @app.route("/right") 66 | def right(): 67 | GPIO.output(17, GPIO.HIGH) 68 | GPIO.output(27, GPIO.LOW) 69 | GPIO.output(23, GPIO.LOW) 70 | GPIO.output(24, GPIO.HIGH) 71 | 72 | sleep(1) 73 | GPIO.output(17, GPIO.LOW) 74 | GPIO.output(27, GPIO.LOW) 75 | GPIO.output(23, GPIO.LOW) 76 | GPIO.output(24, GPIO.LOW) 77 | return redirect("/") 78 | 79 | if __name__ == "__main__": 80 | app.run(host='0.0.0.0', port=8080, debug=True) 81 | -------------------------------------------------------------------------------- /static/assets/css/main.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/victorqribeiro/raspberryCar/ebe98e6f1d39e4408ff254539d2f0c699f09e01e/static/assets/css/main.css -------------------------------------------------------------------------------- /static/assets/js/main.js: -------------------------------------------------------------------------------- 1 | window.SpeechRecognition = window.webkitSpeechRecognition || window.SpeechRecognition; 2 | 3 | const recognition = new window.SpeechRecognition(); 4 | recognition.lang = "en-US"; 5 | recognition.onresult = (e) => analyse( e.results[0][0].transcript.toLowerCase() ); 6 | 7 | recognition.onerror = e => console.error( e ); 8 | 9 | const go = where =>{ 10 | if( where.match(/forward|backward|left|right/) ) 11 | window.location.href = where; 12 | } 13 | 14 | const rules = [ 15 | {rule: /.*go(.*)/, response: 1, action: go } 16 | ]; 17 | 18 | const analyse = msg => { 19 | btn.disabled = false; 20 | let response = "I didn't understand"; 21 | let matches; 22 | for(let i = 0; i < rules.length; i++){ 23 | let r = rules[i]; 24 | matches = r.rule.exec(msg); 25 | if( matches ){ 26 | response = r.response === 1 ? r.action(matches[1]) : r.response ; 27 | break; 28 | } 29 | } 30 | say(response); 31 | } 32 | 33 | const say = msg => { 34 | let what = new SpeechSynthesisUtterance(msg); 35 | what.lang = "en-US"; 36 | speechSynthesis.speak(what); 37 | } 38 | 39 | const btn = document.createElement('button'); 40 | btn.innerText = "Speak"; 41 | 42 | btn.onclick = ()=> { 43 | btn.disabled = true; 44 | recognition.start(); 45 | } 46 | 47 | document.body.appendChild(btn); 48 | -------------------------------------------------------------------------------- /static/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/victorqribeiro/raspberryCar/ebe98e6f1d39e4408ff254539d2f0c699f09e01e/static/images/favicon.png -------------------------------------------------------------------------------- /templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 |