-
Group work: Send a message between two projects
I did the group work with Toni Kyllönen and Joonas Patana. We connected three boards together, two were ATtiny412 boards, one with led and one without, and one was the ESP8266 board with it's led. The boards transmit signals were connected together and same with the receive signals. Then in the boards code the transmit pin was switched to input when ever the board wasn't trying to transmit. This was done so the transmit line wouldn't create a short circuit when other board would be transmitting. I modified the code slightly on my ESP8266 board so the leds state would toggle everytime the correct node would be called. Here is the slightly modified code that I got from our course's moodle page:// Serial BUS example with switching Tx mode // Orgianal code from our course's moodle page. // I just added the ledState to toggle the led. #include
We connected all the boards together using breadboard and connected an FTDI programmer to that so we could just use the Arduino's serial monitor to send and receive messages through serial. In the video you can see the ATtiny412 without the led on the left that acted just as a serial node, in the center is the ATtiny412 that toggled it led always when it's node address was received and in the right is the ESP8266 that flashes the led when there is a transmission coming from the serial and then toggles it's LED on or off if it's node address was called. The ESP8266 address was 3,the LED ATtiny was 6, and the ATtiny without the led was 2.#define txPin 1 // transmit signal to the bridge #define rxPin 3 // recieves signal from bridge SoftwareSerial mySerial(rxPin, txPin); // RX, TX const char node = '3'; // network address const int ledPin = 2; // the number of the LED pin bool ledState = 0; int incomingByte; void setup() { mySerial.begin(9600); pinMode(ledPin, OUTPUT); pinMode(txPin, INPUT); } void loop() { if (mySerial.available() > 0) { digitalWrite(ledPin, LOW); delay(200); digitalWrite(ledPin, HIGH); delay(200); incomingByte = mySerial.read(); if (incomingByte == node) { pinMode(txPin, OUTPUT); // open line to write mySerial.print("node "); mySerial.println(node); pinMode(txPin, INPUT); delay(200); ledState = !ledState; digitalWrite(ledPin, ledState); } } } Downloads
Download SerialBusHelloBoard.ino
-
Individual assignment
We had only two weekdays to do this weeks individual assignment so it is very minimal. I used my desktop PC as TCP server and the ESP8266 board that I built in the input&output weeks as a TCP client. I was running MicroPython on the ESP8266 board, you can check the flashing here and the WiFi setup here.
I found this guide about sockets for Python. I used the echo server code from there, but modified the host address and port. I also changed the response that the server sends to client a bit.# https://realpython.com/python-sockets/#echo-server import socket HOST = '192.168.1.101' # Standard loopback interface address (localhost) PORT = 8000 # Port to listen on (non-privileged ports are > 1023) with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.bind((HOST, PORT)) s.listen() conn, addr = s.accept() with conn: print('Connected by', addr) while True: data = conn.recv(1024) print(str(data, 'utf8')) if not data: break conn.sendall(b'Hi from PC! I received: ' + data)
I thought that I would just try and use the echo client code meant for regular python in MicroPython. The client code was also from the guide linked above. The line:with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
wasn't working in MicroPython so I modified the code and changed the messages a bit.# https://realpython.com/python-sockets/#echo-client import socket HOST = '192.168.1.101' # The server's hostname or IP address PORT = 8000 # The port used by the server s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: s.connect((HOST, PORT)) s.sendall(b'Hello from ESP') data = s.recv(1024) finally: print('Received ', str(data, 'utf8'))
Thewith ... as
method would handle also closing the socket correctly and I don't think that my version does this so it would need further research. Now I could run poth codes and the server on the PC would display the IP address of the ESP8266 that connected to my socket.Downloads
Download echo_server.py
Download echo_client.py -
Final project
UART
In micropython I made an UART test and used the information from micropython docs to initilise it in UART1. During the testing I noticed that the UART1 was still putting out some junk so I changed it to UART2.
import time from machine import UART uart2 = UART(2, baudrate=9600, tx=17, rx=16, bits=8, parity=None, stop=1) while True: uart2.write('test') time.sleep(1)
I tested the UART just by connecting the correct pins to the FTDI programmer and used PuTTY to monitor it.MQTT
I had already installed Mosquitto MQTT broker to my Raspberry pi but it can be simply installed with
sudo apt install mosquitto mosquitto-clients
and you need to set it to auto start on bootsudo systemctl enable mosquitto.service
. You also might want to config the default port and allow anonymous access. To do this just addlistener 1883 allow_anonymous true
to file/etc/mosquitto/mosquitto.conf
I got the MQTT micropython example from micropython github and modified the server to match my MQTT brokers address. Since I had a device that was publishing temperature to topic named lampo, I subsribed to that topic.
import time from umqtt.simple import MQTTClient # Publish test messages e.g. with: # mosquitto_pub -t foo_topic -m hello # Received messages from subscriptions will be delivered to this callback def sub_cb(topic, msg): print((topic, msg)) def main(server="192.168.1.108"): c = MQTTClient("umqtt_client", server) c.set_callback(sub_cb) c.connect() c.subscribe(b"lampo") while True: if True: # Blocking wait for message c.wait_msg() else: # Non-blocking wait for message c.check_msg() # Then need to sleep to avoid 100% CPU usage (in a real # app other useful actions would be performed instead) time.sleep(1) c.disconnect() if __name__ == "__main__": main()
After running the code I could see that the subscribing was working.MQTT passthrough
import time from umqtt.simple import MQTTClient from machine import UART device = '54622D' topic = bytes(f"{device}/raw_in", 'utf8') server = '192.168.1.108' client = device uart2 = UART(2, baudrate=9600, tx=17, rx=16, bits=8, parity=None, stop=1, txbuf=0) def sub_cb(topic, msg): print(topic, msg) uart2.write(msg.decode('utf8').replace('\\n', '\n')) uart_wait(uart2) answer = uart2.readline() print(answer) def uart_wait(uart): for i in range(5): if uart.any() != 0: break time.sleep(0.02) def main(): mqtt = MQTTClient(client, server) mqtt.set_callback(sub_cb) mqtt.connect() mqtt.subscribe(topic) while True: # Non-blocking wait for message mqtt.check_msg() # Then need to sleep to avoid 100% CPU usage (in a real # app other useful actions would be performed instead) time.sleep(1) if __name__ == "__main__": main()