---
# System prepended metadata

title: Embedded UE3

---

# Embedded UE3

# 1. Actuators

## a)

Then investigate the script blink.py and run it. Describe its behavior and add a
picture of your setup

```python
import RPi.GPIO as GPIO
from time import sleep
import logging
# setup logging
logger = logging.getLogger(__name__)
logging.basicConfig(level="INFO")

# set GPIO Mode 
GPIO.setmode(GPIO.BCM)
# setup GPIO pins
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(24, GPIO.OUT)
GPIO.setup(25, GPIO.OUT)
GPIO.output(24, False)
GPIO.output(25, False)

pin=24

try:
   while True:
      button_state = GPIO.input(18)
      logger.info("button state is %s (pressed=%s)",button_state,not bool(button_state))
      if button_state == False:
           pin=24
      else: 
           pin=25
      GPIO.output(pin, True)
      sleep(1)
      GPIO.output(pin, False)
      sleep(1)
except KeyboardInterrupt: 
    logger.info("cleaning up ...")         
    GPIO.cleanup()
```

**Setup:**

![](https://hackmd.io/_uploads/Hk8uFnvE3.png)

**Describe its behavior:**
- On button press, state will be toggled (which is read from GPIO input pin 18). When the button is not pressed, the red LED (pin 24) will blink. When the button is pressed, the green LED (pin 25) will blink.

**Testen**: Pin auf 5V pin setzen. Siehe reference

Reference:
https://de.pinout.xyz/pinout/pin2_5v_stromversorgung#


## b)

Investigate the script blink threaded.py and run it. Describe the differences
to the previous script:

```python
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
import threading
import logging
# setup logging
logger = logging.getLogger(__name__)
logging.basicConfig(level="INFO")


led_pin=24

class Button():
    def __init__(self, channel):
        self.channel = channel
        self._thread=threading.Thread(name='button',target=self.run)
	self._thread.deamon = True
	self._thread_active = True
        self._thread.start()

    def run(self):
        logger.info("button thread started")
        previous = 1
        current = 0
        while self._thread_active:
            time.sleep(0.01)
            current = GPIO.input(self.channel)
            logger.debug("current %s previous %s",current,previous)
 	    if current==1 and previous==0:
                  logger.info("button was pressed and released")
                  self.onButtonPress()
            previous = current

    def onButtonPress(self):
        global led_pin
        if led_pin==24:
 	    	led_pin=25
        else: 
            led_pin=24
        GPIO.output(24, False)
        GPIO.output(25, False)
    def stop(self):
        logger.debug("stopping thread")
        self._thread_active = False

try:
  # setup gpio
  GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP)
  button=Button(18)
  GPIO.setup(24, GPIO.OUT)
  GPIO.setup(25, GPIO.OUT)
  GPIO.output(24, False)
  GPIO.output(25, False)


  while True:
      # toggle gpio
      GPIO.output(led_pin, True)
      time.sleep(1)
      GPIO.output(led_pin, False)
      time.sleep(1)
except KeyboardInterrupt:     
    button.stop()
    logger.info("stopping ...")     
    time.sleep(1)
    GPIO.cleanup()                 

```

**Differences:**
- Toggling instead of holding. 
- Toggling after fallen edge
- Button press is detected faster (because it's only sleeping for 0.01s instead of 1s)

nonblocking


# 2. Connectivity

## a)

**Change the matriculation number:**
```python
def on_connect(client, userdata, flags, rc):
	logger.info('Connected with result code %s',str(rc))
	client.subscribe("12024183", qos=0)
```

Complete the source code of remotecontrol.py so that it correctly switches on
and off the lights, based on received messages
```python
#!/usr/bin/python

from __future__ import division
import time
import paho.mqtt.client as mqtt
import logging
import RPi.GPIO as GPIO
from at.jku.pervasive.eps.mymqttmessages.mymqttmessages_pb2 import *

# setup logging

logger = logging.getLogger(__name__)
logging.basicConfig(level="INFO")

# setup gpio
GPIO.setmode(GPIO.BCM)
LED_RED=25
LED_GREEN=24
GPIO.setup(LED_RED, GPIO.OUT)
GPIO.setup(LED_GREEN, GPIO.OUT)
GPIO.output(LED_RED, False)
GPIO.output(LED_GREEN, False) 

# mqtt connect callback function
def on_connect(client, userdata, flags, rc):
	logger.info('Connected with result code %s',str(rc))
	# Subscribing in on_connect() means that if we lose the connection and
	# reconnect then subscriptions will be renewed.
	client.subscribe("12024183", qos=0)


# mqtt message received callback function
def on_message(client, userdata, msg):
	commandString=str(msg.payload)
	proto_msg = PBMessage()
	try:
		proto_msg.ParseFromString(msg.payload)
	 
		if proto_msg.HasField('ledControl'):
			logger.debug('got message at %s with content %s',str(msg.topic),commandString)
			logger.info('got message from %s (with target %s)',proto_msg.source,proto_msg.target)
			logger.info('ledControl numberic %s %s %s',proto_msg.ledControl.action,proto_msg.ledControl.led,proto_msg.ledControl.toggleRateHz)
			logger.info('ledControl Info %s %s %s',LedAction.Name(proto_msg.ledControl.action),Led.Name(proto_msg.ledControl.led),proto_msg.ledControl.toggleRateHz)
			led_pin=-1

			# Set pin
			if Led.Value('RED')==proto_msg.ledControl.led:
				led_pin=LED_RED
			elif Led.Value('GREEN')==proto_msg.ledControl.led:
				led_pin=LED_GREEN
			else: 
				logger.error('cannot map led %s to pin',Led.Name(proto_msg.ledControl.led))
				return 
			# Set action
			# TODO: Read action from message and control LED
			if proto_msg.ledControl.action == LedAction.Value("OFF"):
				GPIO.output(led_pin, 0) #turn off
			elif proto_msg.ledControl.action == LedAction.Value("ON"):
				GPIO.output(led_pin, 1) #turn on
			elif proto_msg.ledControl.action == LedAction.Value("TOGGLE"):
				current = GPIO.input(led_pin)
				GPIO.output(led_pin, not current)
			else:
				GPIO.output(led_pin,0)
			# end of ledControl processing
		else:
			logger.warn('got message at %s with content %s',str(msg.topic),commandString)
	except:
		logger.warning('Unable to decode message: No valid ProtoBuf Msg received')
# setup mqtt
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message

# connect mqtt
client.connect("iot.soft.uni-linz.ac.at", 1883, 60)
try:
	client.loop_forever()
except (KeyboardInterrupt, SystemExit): 
	logger.info('disconnecting ...')
	client.disconnect()
	time.sleep(1)
	GPIO.cleanup()
```

TODO: 
- Execute and collect 

## b)

```java
public class ProtobufMqttProgram {
    // embeddedsystems2019
    private static final String DEFAULT_TOPIC = "12024183";

    public static void main(String[] args) {
        ProtobufMqttProgram connector = new ProtobufMqttProgram();
        try {
            Thread.sleep(2000);
            // unsubscribe to not consume sent messages
            // connector.sampleClient.unsubscribe(DEFAULT_TOPIC);
            // qos = 2 (exactly once)

            // TODO: Publish different LedControl Messages

            connector.sendLedControl(Led.RED, LedAction.ON, 0);
            Thread.sleep(5000);

            // Publish LedControl with color=red, action=off, togglerate=0
            connector.sendLedControl(Led.RED, LedAction.OFF, 0);

            Thread.sleep(5000);

            // Publish LedControl with color=green, action=on, togglerate=0
            connector.sendLedControl(Led.GREEN, LedAction.ON, 0);

            Thread.sleep(5000);

            // Publish LedControl with color=green, action=off, togglerate=0
            connector.sendLedControl(Led.GREEN, LedAction.OFF, 0);

            Thread.sleep(5000);

            connector.close();
        } catch (MqttException e) {
            processEx(e);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

```
``` 





```

Logs: 
```
INFO:__main__:Connected with result code 0
INFO:__main__:got message from 3576804469 (with target 0)
INFO:__main__:ledControl numberic 1 0 0
INFO:__main__:ledControl Info ON RED 0
INFO:__main__:got message from 3576804469 (with target 0)
INFO:__main__:ledControl numberic 0 0 0
INFO:__main__:ledControl Info OFF RED 0
INFO:__main__:got message from 3576804469 (with target 0)
INFO:__main__:ledControl numberic 1 1 0
INFO:__main__:ledControl Info ON GREEN 0
INFO:__main__:got message from 3576804469 (with target 0)
INFO:__main__:ledControl numberic 0 1 0
INFO:__main__:ledControl Info OFF GREEN 0
```



# 3. Message Format

## a)

Protobuf messages: 
```
connector.sendLedControl(Led.RED, LedAction.ON, 0);
connector.sendLedControl(Led.RED, LedAction.OFF, 0);
connector.sendLedControl(Led.GREEN, LedAction.ON, 0);
connector.sendLedControl(Led.GREEN, LedAction.OFF, 0);
```

Output Protobuf

```
INFO  a.j.p.eps.ProtobufMqttProgram - Connecting to broker: tcp://iot.soft.uni-linz.ac.at:1883
INFO  a.j.p.eps.ProtobufMqttProgram - connected to tcp://iot.soft.uni-linz.ac.at:1883
INFO  a.j.p.eps.ProtobufMqttProgram - message size 11
WARN  a.j.p.eps.ProtobufMqttProgram - got led control from 997924158 with target 0
INFO  a.j.p.eps.ProtobufMqttProgram - message size 9
WARN  a.j.p.eps.ProtobufMqttProgram - got led control from 997924158 with target 0
INFO  a.j.p.eps.ProtobufMqttProgram - message size 13
WARN  a.j.p.eps.ProtobufMqttProgram - got led control from 997924158 with target 0
INFO  a.j.p.eps.ProtobufMqttProgram - message size 11
WARN  a.j.p.eps.ProtobufMqttProgram - got led control from 997924158 with target 0
```

JSON Messages: 
```
{"LED":"RED","ACTION":"TOGGLE","TOGGLERATE":"5"}
{\"LED\":\"GREEN\",\"ACTION\":\"ON\",\"TOGGLERATE\":\"0\"}
{\"LED\":\"BLUE\",\"ACTION\":\"OFF\",\"TOGGLERATE\":\"0\"}
{\"LED\":\"GREEN\",\"ACTION\":\"ON\",\"TOGGLERATE\":\"0\"}
{\"LED\":\"RED\",\"ACTION\":\"OFF\",\"TOGGLERATE\":\"0\"}
{\"LED\":\"BLUE\",\"ACTION\":\"TOGGLE\",\"TOGGLERATE\":\"1\"}
```

Output JSON
```
INFO  at.jku.pervasive.eps.TextMqttProgram - Connecting to broker: tcp://iot.soft.uni-linz.ac.at:1883
INFO  at.jku.pervasive.eps.TextMqttProgram - connected to tcp://iot.soft.uni-linz.ac.at:1883
INFO  at.jku.pervasive.eps.TextMqttProgram - message size 48
INFO  at.jku.pervasive.eps.TextMqttProgram - message size 46
INFO  at.jku.pervasive.eps.TextMqttProgram - message size 46
INFO  at.jku.pervasive.eps.TextMqttProgram - message size 46
INFO  at.jku.pervasive.eps.TextMqttProgram - message size 45
INFO  at.jku.pervasive.eps.TextMqttProgram - message size 49
```

## b)

### Protobuf

Uses binary encoding
- Enums (like LedAction) can be represented with minimal bit amount

```
Led.RED, LedAction.ON, 0
```


### JSON

Uses ASCII encoding
- Instead of representing actions as an enum, they are represented as strings. So we need 6 bytes instead of 2 bits (which is rounded up to 1 byte). 
- There's also lots of useless information needed to structure the message (':' and '{}')

```
"{\"LED\":\"RED\",\"ACTION\":\"TOGGLE\",\"TOGGLERATE\":\"5\"}"
```

