Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
WouterLemaire
Active Contributor
DescriptionHyperlink
OverviewHCP IoT HANA Car v1.0
Internet of Things configurationHANA Car v1.0 - Internet of Things configuration
UI5 Java WebappHANA Car v1.0 – Java Webapp
The Car with raspberry PiHANA Car v1.0 – Raspberry Pi

For controlling the motors of HANA Car I’m using a Raspberry PI 2 model B, a strong battery and a wifi adapter.

The raspberry will connect to the IoT service listen to directions. Everytime the raspberry receives a message/direction it will start the right engine in the right direction.

First I started without the connection to Iot. I just wanted to make the car drive by developing a python script. Before I could develop something I had to connect the motors to the raspberry. Therefore I followed this tutorial:

https://learn.adafruit.com/adafruit-raspberry-pi-lesson-9-controlling-a-dc-motor/hardware


I used the IC L293D for controlling the motor. Each motor has a IC L293. Once everything was connected, I could start with developments on the raspberry pi.


I used this script for testing the motors:

http://computers.tutsplus.com/tutorials/controlling-dc-motors-using-python-with-a-raspberry-pi--cms-...



import RPi.GPIO as GPIO
from time import sleep
GPIO.setmode(GPIO.BOARD)
Motor1A = 16
Motor1B = 18
Motor1E = 22
GPIO.setup(Motor1A,GPIO.OUT)
GPIO.setup(Motor1B,GPIO.OUT)
GPIO.setup(Motor1E,GPIO.OUT)
print "Turning motor on"
GPIO.output(Motor1A,GPIO.HIGH)
GPIO.output(Motor1B,GPIO.LOW)
GPIO.output(Motor1E,GPIO.HIGH)
sleep(2)
print "Stopping motor"
GPIO.output(Motor1E,GPIO.LOW)
GPIO.cleanup()

I don’t put the two motors on one controller because I want to send different actions to each motor.

This was the result after my first script:

You’re probably wondering how I do the steering. Therefore I use a small motor which works like this: (this was already in the car)

After that all worked I added the code for listening to the IoT service. Therefore I started from this script on IoT starter kit:

https://github.com/SAP/iot-starterkit/tree/master/src/code-snippets/python/hcp-iot-services/wss

I combined this code with the code for controlling the motors and end up with the following.

  • setWheel
    • Function to turn the front wheels to left or right
  • stopWheel
    • Function to stop the motor for the steering and put the wheels straight
  • setMotor
    • Function to activate the driving motor in forward, backward or stop.
  • IoTServicesClientProtocol
    • this is the implementation of the websocket
    • onOpen function
      • I use this function to create a second thread and keep the connection alive between HCP and the raspberry pi. I noticed that after 60 seconds without communication the websocket will lose the connection. Therefore I send a message from the raspberry pi to IoT every 30 seconds.
    • onMessage
      • Every message from HCP will be catched by the websocket in this function. This is also the place where I activate the right engine.
        • F --> forward and stop steering
        • B --> backward and stop steering
        • L --> left ( will still go forward of backward depending on previous message)
        • R --> right ( will still go forward of backward depending on previous message)
        • N --> disable all engines
  • Other code is used to start the websocket


import RPi.GPIO as GPIO
import time
import simplejson as json
import sys
import thread
from optparse import OptionParser
from twisted.python import log
from twisted.internet import reactor, ssl
from autobahn.twisted.websocket import WebSocketClientFactory, \
    WebSocketClientProtocol, \
    connectWS
from base64 import b64encode
GPIO.setmode(GPIO.BCM)
enable_pin = 12
coil_A_1_pin = 5
coil_A_2_pin = 6
enable_pin2 = 16
coil_B_1_pin = 20
coil_B_2_pin = 21
GPIO.setup(enable_pin,GPIO.OUT)
GPIO.setup(coil_A_1_pin, GPIO.OUT)
GPIO.setup(coil_A_2_pin, GPIO.OUT)
GPIO.setup(enable_pin2,GPIO.OUT)
GPIO.setup(coil_B_1_pin, GPIO.OUT)
GPIO.setup(coil_B_2_pin, GPIO.OUT)
GPIO.output(enable_pin,1)
GPIO.output(enable_pin2,1)
def setWheel(m1,m2):
    GPIO.output(coil_B_1_pin, m1)
    GPIO.output(coil_B_2_pin, m2)
def stopWheel():
    GPIO.output(coil_B_1_pin, 0)
    GPIO.output(coil_B_2_pin, 0)
def setMotor(m1,m2):
    GPIO.output(coil_A_1_pin, m1)
    GPIO.output(coil_A_2_pin, m2)
def keepAlive(websocket):
    while True:
        print("Keep Alive")
        websocket.sendToHCP()
        time.sleep(30)
class IoTServicesClientProtocol(WebSocketClientProtocol):
    def sendToHCP(self):
# send message of Message Type 1 and the corresponding payload layout that you defined in the IoT Services Cockpit
        self.sendMessage('{"mode":"async", "messageType":"<messagetypeid>", "messages":[{"timestamp":1413191650,"action":"d"}]}'.encode('utf8'))
        print("keep alive");
    def onOpen(self):
        print("connection open")
        try:
            print("start thread")
            thread.start_new_thread(keepAlive,(self, ))
        except:
            print("Error starting thread")
    def onMessage(self, payload, isBinary):
        if not isBinary:
            data = ""
            data = json.loads(format(payload.decode('utf8')))
            try:
                print(data['messages'][0]['action'])
                action = data['messages'][0]['action'];
                if action == "f":
                    setMotor(0,1)
                    stopWheel()
                    #time.sleep(1)
                    #setMotor(0,0)
                elif action == "b":
                    setMotor(1,0)
                    stopWheel()
                    #time.sleep(1)
                    #setMotor(0,0)
                elif action == "l":
                    setWheel(0,1)
                elif action == "r":
                    setWheel(1,0)
                else:
                    setMotor(0,0)
                    stopWheel()
            except:
                print("alive")
       
if __name__ == '__main__':
    log.startLogging(sys.stdout)
    parser = OptionParser()
# interaction for a specific Device instance - replace 1 with your specific Device ID
    parser.add_option("-u", "--url", dest="url", help="The WebSocket URL", default="wss://iotmmsptrial.hanatrial.ondemand.com/com.sap.iotservices.mms/v1/api/ws/data/<deviceid>")
    (options, args) = parser.parse_args()
    # create a WS server factory with our protocol
    ##
    factory = WebSocketClientFactory(options.url, debug=False)
    headers={'Authorization': 'Bearer ' + '<bearertokenid>'}
    # print(headers)
    factory = WebSocketClientFactory(options.url, headers=headers, debug=False)
    factory.protocol = IoTServicesClientProtocol
    # SSL client context: default
    ##
    if factory.isSecure:
        contextFactory = ssl.ClientContextFactory()
    else:
        contextFactory = None
 
    instance = connectWS(factory, contextFactory)
    reactor.run()
 


Added the full code as attachement, just remove ".txt"

Demo

Hope you enjoyed the blogs :smile:

Kind regards,

Wouter

Labels in this area