Showing posts with label Python. Show all posts
Showing posts with label Python. Show all posts

Wednesday, June 30, 2021

UDP communication between Raspberry Pi/Python and Arduino Nano RP2040 Connect.

This exercise run on Raspberry Pi/Python and Arduino Nano RP2040 Connect, communicate in UDP.

WiFiNINA is needed, install it in Arduino IDE's Library Manager. 

Exercise 1: Simple UDP example.

With WiFiNINA installed and board of Arduino Nano RP2040 Connect selected, you can load WiFiNINA example WiFiUdpSendReceiveString. Remember to update ssid and password in arduino_secrets.h to match your WiFi network. Upload it to Nano RP2040, open Serial Monitor, it will connect to the WiFi network. Check the ip show in Serial Monitor.

In Raspberry Pi side, run the Python code with matched UDP_IP; simple send message to nano RP2040 via UDP.

pyUDP_client_20210630.py
# ref:
# https://wiki.python.org/moin/UdpCommunication
import socket

#UDP_IP = "127.0.0.1"
#UDP_PORT = 5005
UDP_IP = "192.168.197.39"
UDP_PORT = 2390
MESSAGE = b"Hello, World!"

print("UDP target IP: %s" % UDP_IP)
print("UDP target port: %s" % UDP_PORT)
print("message: %s" % MESSAGE)

sock = socket.socket(socket.AF_INET, # Internet
                     socket.SOCK_DGRAM) # UDP
sock.sendto(MESSAGE, (UDP_IP, UDP_PORT))

Exercise 2: With GUI using PyQt5

Keep WiFiUdpSendReceiveString run on Nano RP2040.

In Raspberry Pi side, run following code with GUI.

pyQt5_UDP_client_20210630.py
import sys
from pkg_resources import require

from PyQt5.QtWidgets import (QApplication, QWidget, QLabel,
                             QTextEdit, QPushButton,
                             QVBoxLayout, QMessageBox)
from PyQt5.QtGui import QFont

from PyQt5.QtNetwork import QUdpSocket, QHostAddress

UDP_IP = "192.168.197.39"
UDP_PORT = 2390

print("Python version")
print(sys.version)
print()

class AppWindow(QWidget):
    
    def __init__(self):
        super().__init__()
        
        self.sock = QUdpSocket(self)
        self.sock.bind(QHostAddress(UDP_PORT), UDP_PORT)
        self.sock.readyRead.connect(self.sock_readyRead_slot)
        
        lbAppTitle = QLabel('Python UDP Client to send msg')
        lbAppTitle.setFont(QFont('Anton', 15, QFont.Bold))
        lbSysInfo = QLabel('Python:\n' + sys.version)
        vboxInfo = QVBoxLayout()
        vboxInfo.addWidget(lbAppTitle)
        vboxInfo.addWidget(lbSysInfo)
        
        self.edMsg = QTextEdit()
        btnSend = QPushButton("Send")
        btnSend.clicked.connect(self.btnSend_Clicked)
        vboxMsg = QVBoxLayout()
        vboxMsg.addWidget(self.edMsg)
        vboxMsg.addWidget(btnSend)
        
        vboxMain = QVBoxLayout()
        vboxMain.addLayout(vboxInfo)
        vboxMain.addLayout(vboxMsg)
        vboxMain.addStretch()
        self.setLayout(vboxMain)
        
        self.setGeometry(100, 100, 500,400)
        self.show()
        
    def sock_readyRead_slot(self):
        while self.sock.hasPendingDatagrams():
            datagram, host, port = self.sock.readDatagram(
                self.sock.pendingDatagramSize()
            )
            
            print("rx:")
            message = '{}\nHost: {}\nPort: {}\n\n'.format(datagram.decode(),
                                                          host.toString(),
                                                          port)

            print(message)
            print()
        
    def btnSend_Clicked(self):
        msgToSend = self.edMsg.toPlainText()
        print("tx:")
        print(msgToSend)
        print()
        
        datagram = msgToSend.encode()
        self.sock.writeDatagram(datagram, QHostAddress(UDP_IP), UDP_PORT)
        
    def closeEvent(self, event):
        close = QMessageBox.question(
            self,
            "QUIT",
            "Close Application?",
            QMessageBox.Yes | QMessageBox.No)
        if close == QMessageBox.Yes:
            print("Close")
            event.accept()
        else:
            event.ignore()

if __name__ == '__main__':
    print('run __main__')
    app = QApplication(sys.argv)
    window = AppWindow()
    sys.exit(app.exec_())

print("- bye -")

Exercise 3: Raspberry Pi/Python remote control Nano RP2040 onboard RGB LED via UDP.

In Nano RP2040, modify to control onboard RGB LED base on incoming command: start with "#RGB", follow with three bytes for R, G and B.
WiFiUdp_RGB__20210630.ino
/*
  WiFi UDP to control Nano RP2040 Connect onboard RGB
 */
#include <SPI.h>
#include <WiFiNINA.h>
#include <WiFiUdp.h>

int status = WL_IDLE_STATUS;
#include "arduino_secrets.h" 
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID;  // your network SSID (name)
char pass[] = SECRET_PASS;  // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0;           // your network key index number (needed only for WEP)

unsigned int localPort = 2390;      // local port to listen on

char packetBuffer[256]; //buffer to hold incoming packet
char  ReplyBuffer[] = "acknowledged";       // a string to send back

WiFiUDP Udp;

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600);

  pinMode(LEDR, OUTPUT);
  pinMode(LEDG, OUTPUT);
  pinMode(LEDB, OUTPUT);

  analogWrite(LEDR, 0);
  analogWrite(LEDG, 0);
  analogWrite(LEDB, 0);
  
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  analogWrite(LEDR, 255);
  analogWrite(LEDG, 255);
  analogWrite(LEDB, 255);

  // check for the WiFi module:
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    // don't continue
    while (true);
  }

  String fv = WiFi.firmwareVersion();
  if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
    Serial.println("Please upgrade the firmware");
  }

  // attempt to connect to WiFi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }
  Serial.println("Connected to WiFi");
  printWifiStatus();

  Serial.println("\nStarting connection to server...");
  // if you get a connection, report back via serial:
  Udp.begin(localPort);

  analogWrite(LEDR, 0);
  analogWrite(LEDG, 0);
  analogWrite(LEDB, 0);
}

void loop() {

  // if there's data available, read a packet
  int packetSize = Udp.parsePacket();
  if (packetSize) {
    Serial.print("Received packet of size ");
    Serial.println(packetSize);
    Serial.print("From ");
    IPAddress remoteIp = Udp.remoteIP();
    Serial.print(remoteIp);
    Serial.print(", port ");
    Serial.println(Udp.remotePort());

    // read the packet into packetBufffer
    int len = Udp.read(packetBuffer, 255);
    if (len > 0) {
      packetBuffer[len] = 0;
    }
    Serial.println("Contents:");
    Serial.println(packetBuffer);

    // send a reply, to the IP address and port that sent us the packet we received
    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write(ReplyBuffer);
    Udp.endPacket();

    String cmd = String(packetBuffer);
    if(cmd.startsWith("#RGB")){
      Serial.println("CMD: #RGB");
      int valR = (int)(packetBuffer[4]);
      int valG = (int)(packetBuffer[5]);
      int valB = (int)(packetBuffer[6]);
      Serial.println("R: " + String(valR));
      Serial.println("G: " + String(valG));
      Serial.println("B: " + String(valB));

      analogWrite(LEDR, 255-valR);
      analogWrite(LEDG, 255-valG);
      analogWrite(LEDB, 255-valB);
    }else{
      Serial.println("NOT MATCH");
    }

  }
}


void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your board's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}

In Raspberry Pi side:

pyQt5_UDP_client_RGB_20210630.py
import sys
from pkg_resources import require

from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (QApplication, QWidget, QLabel,
                             QSlider, QPushButton,
                             QVBoxLayout, QHBoxLayout, QMessageBox)
from PyQt5.QtGui import QFont

from PyQt5.QtNetwork import QUdpSocket, QHostAddress

UDP_IP = "192.168.197.39"
UDP_PORT = 2390

print("Python version")
print(sys.version)
print()

class AppWindow(QWidget):
    
    def __init__(self):
        super().__init__()
        
        self.sock = QUdpSocket(self)
        self.sock.bind(QHostAddress(UDP_PORT), UDP_PORT)
        self.sock.readyRead.connect(self.sock_readyRead_slot)
        
        lbAppTitle = QLabel('Python UDP Client to control RGB')
        lbAppTitle.setFont(QFont('Anton', 15, QFont.Bold))
        lbSysInfo = QLabel('Python:\n' + sys.version)
        vboxInfo = QVBoxLayout()
        vboxInfo.addWidget(lbAppTitle)
        vboxInfo.addWidget(lbSysInfo)

        
        lbR = QLabel(' R: ')
        self.sliderR = QSlider(Qt.Horizontal, self)
        self.sliderR.setRange(0, 255)
        self.sliderR.valueChanged.connect(self.sliderRGB_valueChanged_slot)
        boxR = QHBoxLayout()
        boxR.addWidget(lbR)
        boxR.addWidget(self.sliderR)
        
        lbG = QLabel(' G: ')
        self.sliderG = QSlider(Qt.Horizontal, self)
        self.sliderG.setRange(0, 255)
        self.sliderG.valueChanged.connect(self.sliderRGB_valueChanged_slot)
        boxG = QHBoxLayout()
        boxG.addWidget(lbG)
        boxG.addWidget(self.sliderG)
        
        lbB = QLabel(' B: ')
        self.sliderB = QSlider(Qt.Horizontal, self)
        self.sliderB.setRange(0, 255)
        self.sliderB.valueChanged.connect(self.sliderRGB_valueChanged_slot)
        boxB = QHBoxLayout()
        boxB.addWidget(lbB)
        boxB.addWidget(self.sliderB)
        
        boxRGB = QVBoxLayout()
        boxRGB.addLayout(boxR)
        boxRGB.addLayout(boxG)
        boxRGB.addLayout(boxB)
        
        btnSend = QPushButton("Update")
        btnSend.clicked.connect(self.btnSend_Clicked)
        vboxMsg = QVBoxLayout()
        vboxMsg.addLayout(boxRGB)
        vboxMsg.addWidget(btnSend)
        
        vboxMain = QVBoxLayout()
        vboxMain.addLayout(vboxInfo)
        vboxMain.addLayout(vboxMsg)
        vboxMain.addStretch()
        self.setLayout(vboxMain)
        
        self.setGeometry(100, 100, 500,400)
        self.show()
        
    def sock_readyRead_slot(self):
        while self.sock.hasPendingDatagrams():
            datagram, host, port = self.sock.readDatagram(
                self.sock.pendingDatagramSize()
            )
            
            print("rx:")
            message = '{}\nHost: {}\nPort: {}\n\n'.format(datagram.decode(),
                                                          host.toString(),
                                                          port)

            print(message)
            print()
        
    def btnSend_Clicked(self):
        print("tx:")
        
        valueR = self.sliderR.value()
        valueG = self.sliderG.value()
        valueB = self.sliderB.value()
        
        CMD_RGB = "#RGB"
        bCMD_RGB = str.encode(CMD_RGB) + bytes([valueR, valueG, valueB])
        print(type(bCMD_RGB))
        print("CMD: ", bCMD_RGB)
        
        self.sock.writeDatagram(bCMD_RGB, QHostAddress(UDP_IP), UDP_PORT)
        
        """
        msgToSend = self.edMsg.toPlainText()
        print("tx:")
        print(msgToSend)
        print()
        
        datagram = msgToSend.encode()
        self.sock.writeDatagram(datagram, QHostAddress(UDP_IP), UDP_PORT)
        """
        
    def sliderRGB_valueChanged_slot(self):
        print("sliderRGB_valueChanged_slot")
        valueR = self.sliderR.value()
        valueG = self.sliderG.value()
        valueB = self.sliderB.value()
        print(" R: ", valueR, " G: ", valueG, " B: ", valueB)
        
        CMD_RGB = "#RGB"
        bCMD_RGB = str.encode(CMD_RGB) + bytes([valueR, valueG, valueB])
        print(type(bCMD_RGB))
        print(bCMD_RGB)
        
    def closeEvent(self, event):
        close = QMessageBox.question(
            self,
            "QUIT",
            "Close Application?",
            QMessageBox.Yes | QMessageBox.No)
        if close == QMessageBox.Yes:
            print("Close")
            event.accept()
        else:
            event.ignore()

if __name__ == '__main__':
    print('run __main__')
    app = QApplication(sys.argv)
    window = AppWindow()
    sys.exit(app.exec_())

print("- bye -")


~ More exercise of Arduino Nano RP2040 Connect.

Sunday, June 13, 2021

Raspberry Pi/Python BLE Central + Arduino Nano RP2040 Connect BLE Peripheral

This exercise implement Python 3 code run on Raspberry Pi act as BLE Central, connect to Arduino Nano RP2040 Connect act as BLE Peripheral. And send data (0x01/0x00) to turn the Nano RP2040 Connect's onboard LED ON/OFF.


Arduino Nano RP2040 Connect act as BLE Peripheral side:

- Make sure ArduinoBLE library is installed.

- The Arduino code is modified from ArduinoBLE Examples > Peripheral > CallbackLED. With MAC, Service UUID, Characteristic UUID, and BLE written data displayed. Such that we can program Central side accordingly.

nanoRP2040_BLE_CallbackLED.ino
/*
  Callback LED

  This example creates a BLE peripheral with service that contains a
  characteristic to control an LED. The callback features of the
  library are used.

  The circuit:
  - Arduino MKR WiFi 1010, Arduino Uno WiFi Rev2 board, Arduino Nano 33 IoT,
    Arduino Nano 33 BLE, or Arduino Nano 33 BLE Sense board.

  You can use a generic BLE central app, like LightBlue (iOS and Android) or
  nRF Connect (Android), to interact with the services and characteristics
  created in this sketch.

  This example code is in the public domain.
*/

#include <ArduinoBLE.h>

BLEService ledService("19B10000-E8F2-537E-4F6C-D104768A1214"); // create service

// create switch characteristic and allow remote device to read and write
BLEByteCharacteristic switchCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);

const int ledPin = LED_BUILTIN; // pin to use for the LED

void setup() {
  Serial.begin(9600);
  while (!Serial);
  delay(1000);
  Serial.println("\n--- Start---");
  
  pinMode(ledPin, OUTPUT); // use the LED pin as an output

  // begin initialization
  if (!BLE.begin()) {
    Serial.println("starting BLE failed!");

    while (1);
  }

  Serial.print("My BLE MAC:\t\t ");
  Serial.println(BLE.address());
  Serial.print("Service UUID:\t\t ");
  Serial.println(ledService.uuid());
  Serial.print("Characteristic UUID:\t ");
  Serial.println(switchCharacteristic.uuid());
  Serial.println();

  // set the local name peripheral advertises
  BLE.setLocalName("LEDCallback");
  // set the UUID for the service this peripheral advertises
  BLE.setAdvertisedService(ledService);

  // add the characteristic to the service
  ledService.addCharacteristic(switchCharacteristic);

  // add service
  BLE.addService(ledService);

  // assign event handlers for connected, disconnected to peripheral
  BLE.setEventHandler(BLEConnected, blePeripheralConnectHandler);
  BLE.setEventHandler(BLEDisconnected, blePeripheralDisconnectHandler);

  // assign event handlers for characteristic
  switchCharacteristic.setEventHandler(BLEWritten, switchCharacteristicWritten);
  // set an initial value for the characteristic
  switchCharacteristic.setValue(0);

  // start advertising
  BLE.advertise();

  Serial.println(("Bluetooth device active, waiting for connections..."));
}

void loop() {
  // poll for BLE events
  BLE.poll();
}

void blePeripheralConnectHandler(BLEDevice central) {
  // central connected event handler
  Serial.print("Connected event, central: ");
  Serial.println(central.address());
}

void blePeripheralDisconnectHandler(BLEDevice central) {
  // central disconnected event handler
  Serial.print("Disconnected event, central: ");
  Serial.println(central.address());
}

void switchCharacteristicWritten(BLEDevice central, BLECharacteristic characteristic) {
  // central wrote new value to characteristic, update LED
  Serial.println("Characteristic event, written: ");

  byte charValue = switchCharacteristic.value();
  Serial.println(charValue);

  if (charValue) {
    Serial.println("LED on");
    digitalWrite(ledPin, HIGH);
  } else {
    Serial.println("LED off");
    digitalWrite(ledPin, LOW);
  }
}

Raspberry Pi/Python BLE Central Side:
- bluepy library is used to control Bluetooth BLE.

To install bluepy for Python3, enter the command:
$ sudo pip3 install bluepy

- tkinter is used for GUI.

py_BLE_Central_LedControl.py connect to Peripheral with matched MAC, and search for service/characteristic with match UUID. Then send 0x01/0x00 to turn ON/OFF the Nano RP2040 Connect's onboard LED.

"""
Python/Raspberry Pi BluetoothLE exercise:
using bluepy library

Work with Arduino Nano RP2040 Connect example:
ArduinoBLE > Peripheral > CallbackLED

Connect to Peripheral with matched MAC.
Check for service uuid and characteristic uuid,
if matched found: send bytes 0x01 and 0x00 for three time
to turn Nano RP2040 Connect onboard LED ON/OFF.
"""

from bluepy import btle
import time

#Have to match with Peripheral
MAC = "84:cc:a8:2e:8d:76"
SERVICE_UUID = "19b10000-e8f2-537e-4f6c-d104768a1214"
CHARACTERISTIC_UUID = "19b10001-e8f2-537e-4f6c-d104768a1214"

nanoRP2040_Char = None

print("Hello")

print("Connect to:" + MAC)
dev = btle.Peripheral(MAC)
print("\n--- dev ----------------------------")
print(type(dev))
print(dev)

print("\n--- dev.services -------------------")
for svc in dev.services:
    print(str(svc))
    
print("\n------------------------------------")
print("Get Serice By UUID: " + SERVICE_UUID)
service_uuid = btle.UUID(SERVICE_UUID)
service = dev.getServiceByUUID(service_uuid)

print(service)
print("\n--- service.getCharacteristics() ---")
print(type(service.getCharacteristics()))
print(service.getCharacteristics())

#----------------------------------------------
characteristics = dev.getCharacteristics()
print("\n--- dev.getCharacteristics() -------")
print(type(characteristics))
print(characteristics)
    
for char in characteristics:
    print("----------")
    print(type(char))
    print(char)
    print(char.uuid)
    if(char.uuid == CHARACTERISTIC_UUID ):
        print("=== !CHARACTERISTIC_UUID matched! ==")
        nanoRP2040_Char = char
        print(char)
        print(dir(char))
        #print(char.getDescriptors)
        #print(char.propNames)
        #print(char.properties)
        #print(type(char.read()))
        print(char.read())
        
bytes_ON = b'\x01'
bytes_OFF = b'\x00'

if nanoRP2040_Char != None:
    print("\nnanoRP2040_Char found")
    print(nanoRP2040_Char)
    for i in range(3):
        nanoRP2040_Char.write(bytes_ON, True)
        print(nanoRP2040_Char.read())
        time.sleep(1.0)
        nanoRP2040_Char.write(bytes_OFF, True)
        print(nanoRP2040_Char.read())
        time.sleep(1.0)
else:
    print("\nnanoRP2040_Char NOT found!")
#=============================================
dev.disconnect()
print("\n--- bye ---\n")
pyTk_BLE_Central_LedControl.py implement GUI with tkinter, user click on button to turn ON/OFF LED.
"""
Python/Raspberry Pi BluetoothLE exercise:
using bluepy library

Work with Arduino Nano RP2040 Connect example:
ArduinoBLE > Peripheral > CallbackLED

Connect to Peripheral with matched MAC.
Check for service uuid and characteristic uuid,
if matched found:
    Start GUI to control Nano RP2040 Connect onboard LED
"""

from bluepy import btle
import time
import tkinter as tk

#Have to match with Peripheral
MAC = "84:cc:a8:2e:8d:76"
SERVICE_UUID = "19b10000-e8f2-537e-4f6c-d104768a1214"
CHARACTERISTIC_UUID = "19b10001-e8f2-537e-4f6c-d104768a1214"

nanoRP2040_Char = None

def toggle():
    if toggle_btn.config('relief')[-1] == 'sunken':
        toggle_btn.config(relief="raised")
        nanoRP2040_Char.write(bytes_OFF, True)
        toggle_btn['text'] = 'Turn LED ON'
    else:
        toggle_btn.config(relief="sunken")
        nanoRP2040_Char.write(bytes_ON, True)
        toggle_btn['text'] = 'Turn LED OFF'

print("Hello")

print("Connect to:" + MAC)
dev = btle.Peripheral(MAC)
print("\n--- dev ----------------------------")
print(type(dev))
print(dev)

print("\n--- dev.services -------------------")
for svc in dev.services:
    print(str(svc))
    
print("\n------------------------------------")
print("Get Serice By UUID: " + SERVICE_UUID)
service_uuid = btle.UUID(SERVICE_UUID)
service = dev.getServiceByUUID(service_uuid)

print(service)
print("\n--- service.getCharacteristics() ---")
print(type(service.getCharacteristics()))
print(service.getCharacteristics())

#----------------------------------------------
characteristics = dev.getCharacteristics()
print("\n--- dev.getCharacteristics() -------")
print(type(characteristics))
print(characteristics)
    
for char in characteristics:
    print("----------")
    print(type(char))
    print(char)
    print(char.uuid)
    if(char.uuid == CHARACTERISTIC_UUID ):
        print("=== !CHARACTERISTIC_UUID matched! ==")
        nanoRP2040_Char = char
        print(char)
        print(dir(char))
        #print(char.getDescriptors)
        #print(char.propNames)
        #print(char.properties)
        #print(type(char.read()))
        print(char.read())
        
bytes_ON = b'\x01'
bytes_OFF = b'\x00'

if nanoRP2040_Char != None:
    print("\nnanoRP2040_Char found")
    print(nanoRP2040_Char)
    
    root = tk.Tk()
    label = tk.Label( root, text="Toggle button to Turn ON/OFF the nano RP040 Connect LED")
    label.pack(pady=10)
    toggle_btn = tk.Button(text="Turn LED ON", width=12, relief="raised", command=toggle)

    toggle_btn.pack(pady=10)
    root.geometry("500x200")

    #Place tkinter window center
    root.eval('tk::PlaceWindow %s center' % root.winfo_pathname(root.winfo_id()))
    root.title("arduino-er.blogspot.com")
    root.mainloop()
else:
    print("\nnanoRP2040_Char NOT found!")
#=============================================
dev.disconnect()
print("\n--- bye ---\n")


~ More exercises of Arduino Nano RP2040 Connect.

Wednesday, January 20, 2021

ESP32 BLE_notify example, handle Notification with Python/Raspberry Pi.

ESP32 BLE_notify example create a BLE server that, once we receive a connection, will send periodic notifications.

In ESP32 side, load
Examples > ESP32 BLE Arduino > BLE_notify

Tested on ESP32-DevKitC V4 in my case.

I implemented a simple Python code run on Raspberry Pi, connect to ESP32 and handle notification.

BLE_notify.ino
/*
    Video: https://www.youtube.com/watch?v=oCMOYS71NIU
    Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleNotify.cpp
    Ported to Arduino ESP32 by Evandro Copercini
    updated by chegewara

   Create a BLE server that, once we receive a connection, will send periodic notifications.
   The service advertises itself as: 4fafc201-1fb5-459e-8fcc-c5c9c331914b
   And has a characteristic of: beb5483e-36e1-4688-b7f5-ea07361b26a8

   The design of creating the BLE server is:
   1. Create a BLE Server
   2. Create a BLE Service
   3. Create a BLE Characteristic on the Service
   4. Create a BLE Descriptor on the characteristic
   5. Start the service.
   6. Start advertising.

   A connect hander associated with the server starts a background task that performs notification
   every couple of seconds.
*/
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>

BLEServer* pServer = NULL;
BLECharacteristic* pCharacteristic = NULL;
bool deviceConnected = false;
bool oldDeviceConnected = false;
uint32_t value = 0;

// See the following for generating UUIDs:
// https://www.uuidgenerator.net/

#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"


class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      deviceConnected = true;
    };

    void onDisconnect(BLEServer* pServer) {
      deviceConnected = false;
    }
};



void setup() {
  Serial.begin(115200);

  // Create the BLE Device
  BLEDevice::init("ESP32");

  // Create the BLE Server
  pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());

  // Create the BLE Service
  BLEService *pService = pServer->createService(SERVICE_UUID);

  // Create a BLE Characteristic
  pCharacteristic = pService->createCharacteristic(
                      CHARACTERISTIC_UUID,
                      BLECharacteristic::PROPERTY_READ   |
                      BLECharacteristic::PROPERTY_WRITE  |
                      BLECharacteristic::PROPERTY_NOTIFY |
                      BLECharacteristic::PROPERTY_INDICATE
                    );

  // https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml
  // Create a BLE Descriptor
  pCharacteristic->addDescriptor(new BLE2902());

  // Start the service
  pService->start();

  // Start advertising
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  pAdvertising->setScanResponse(false);
  pAdvertising->setMinPreferred(0x0);  // set value to 0x00 to not advertise this parameter
  BLEDevice::startAdvertising();
  Serial.println("Waiting a client connection to notify...");
}

void loop() {
    // notify changed value
    if (deviceConnected) {
        pCharacteristic->setValue((uint8_t*)&value, 4);
        pCharacteristic->notify();
        value++;
        delay(3); // bluetooth stack will go into congestion, if too many packets are sent, in 6 hours test i was able to go as low as 3ms
    }
    // disconnecting
    if (!deviceConnected && oldDeviceConnected) {
        delay(500); // give the bluetooth stack the chance to get things ready
        pServer->startAdvertising(); // restart advertising
        Serial.println("start advertising");
        oldDeviceConnected = deviceConnected;
    }
    // connecting
    if (deviceConnected && !oldDeviceConnected) {
        // do stuff here on connecting
        oldDeviceConnected = deviceConnected;
    }
}


Next:

Friday, February 8, 2019

Zerynth, middleware for IoT, you can program 32-bit microcontrollers using C/Python

With Zerynth you can program in Python or hybrid C/Python language the most popular 32-bit microcontrollers including ESP32, and connect them to the top Cloud infrastructures.

Read more: https://www.zerynth.com/



Python on ESP32 DevKitC using Zerynth Studio - Hello World

Friday, June 16, 2017

Python run on Raspberry Pi (and PC running Ubuntu) to plot serial data from ESP8266/NodeMCU

Last post show a simple program run on ESP8266/NodeMCU to read Analog Input and send to Serial. And display the data on Raspberry Pi 3 using Arduino IDE Serial Plotted. This post show a Python example run on Raspberry Pi 3/Raspbian Jessie with PIXEL, to plot the serial data graphically using matplotlib library.



pyserialplot.py
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import serial
import platform

print("Python version: " + platform.python_version())
print("matplotlib version: " + mpl.__version__)

fig, ax = plt.subplots()
line, = ax.plot(np.random.rand(10))
ax.set_ylim(0, 1030)
xdata, ydata = [0]*100, [0]*100
SerialIn = serial.Serial("/dev/ttyUSB0",9600)

def update(data):
    line.set_ydata(data)
    return line,

def run(data):
    global xdata, ydata
    x,y = data
    if (x == 0):
        xdata = [0]*100
        ydata = [0]*100
    del xdata[0]
    del ydata[0]
    xdata.append(x)
    ydata.append(y)
    line.set_data(xdata, ydata)
    return line,

def data_gen():
    x = 9
    while True:
        if (x >= 9):
            x = 0
        else:
            x += 0.1
            
        try:
            inRaw = SerialIn.readline()
            inInt = int(inRaw)
        except:
            inInt = 0
            
        yield x, inInt

ani = animation.FuncAnimation(fig, run, data_gen, interval=0, blit=True)
plt.show()


This python example can be run on both Python 2 and 3. To run this on Raspberry Pi/Raspbian Jessie with PIXEL, matplotlib library is need.

For Python 2:
$ sudo apt-get install python-matplotlib

For Python 3:
$ sudo apt-get install python3-matplotlib

In the following code, we have to get the port connected.
SerialIn = serial.Serial("/dev/ttyUSB0",9600)

In Raspberry Pi/Raspbian Jessie with PIXEL, it is /dev/ttyUSB0 normal. We can check it with:
$ ls /dev/ttyUSB0*




Run on Ubuntu:

The Python script work on PC/Ubuntu also. This video show running on Ubuntu 17.04/Payton 3.6 (actually behind Windows 10/VirtualBox).


In order to run with newest Python 3.6 on Ubuntu 17.04, you have to install Python 3.6 and corresponding IDLE and pip.

And install packages using command:
$ sudo python3.6 -m pip install numpy
$ sudo python3.6 -m pip install matplotlib
$ sudo python3.6 -m pip install pyserial


About Saving graph of matplotlib:

Suppose I can click the Save button on matplotlib navigation toolbar to save the graph to file (reference: matplotlib - Interactive navigation).

But when I test it on Raspberry Pi with matplotlib 1.4.2, it is not work.

When test it on PC running Ubuntu 17.04/Python 3.6 with matplotlib 2.0.2, I can save the graph. But the navigation toolbar disappear after saved.



Friday, May 22, 2015

Arduino Due + ESP8266 as client, connect to Python SimpleHTTPServer

Last post show the program of "Arduino Due + ESP8266 as client, connect to website". We can also host our simple web server using python SimpleHTTPServer.

- It's assumed you have Python installed.
- Create a simple "index.html".
- Start the python SimpleHTTPServer with command:
$ python -m SimpleHTTPServer

Now you can visit http://<ip address>:8000 using browser, in the same network.

SimpleHTTPServer will check for file named index.html or index.htm in current directory. If found, the file’s contents are returned; otherwise a directory listing are returned.

Then you can update the Arduino code in last post "Arduino Due + ESP8266 as client, connect to website" to load the index.html.


Monday, April 6, 2015

Python auto detect Arduino connected serial port

This example TRY to detect Arduino Uno connected serial port automatically, such that no need to hard code "'ttyACM0", "'ttyACM1"... It run on both Python 2 and 3. I test it on Ubuntu Linux only. It's a trial experience only, not a complete solution.



PySerial (ref: http://pyserial.sourceforge.net/pyserial_api.html) provide a function serial.tools.list_ports.comports(), it return an iterable that yields tuples of three strings:
- port name as it can be passed to serial.Serial or serial.serial_for_url()
- description in human readable form
- sort of hardware ID. E.g. may contain VID:PID of USB-serial adapters.

Items are returned in no particular order. It may make sense to sort the items. Also note that the reported strings are different across platforms and operating systems, even for the same device.

To simplify, I assume the port name (eg. /dev/ttyACM0) is in the 1st item returned, and have not handle any other case.

As shown in the post "Get idVendor and idProduct of your Arduino/USB devices", we know VID:PID of Arduino Uno is 2341:0043. So we can compare it with what returned from serial.tools.list_ports.comports() to determine is it Arduino Uno. And for simplify also, I assume it's in VID:PID=2341:0043 format.

findUno.py
import serial.tools.list_ports
import sys
import atexit
import platform

print("=== Auto scan for Arduino Uno connected port===")
print("")
print(platform.system(), platform.release())
print(platform.dist())
print("Python version " + platform.python_version())
print("")

def findArduinoUnoPort():
    portList = list(serial.tools.list_ports.comports())
    for port in portList:
        if "VID:PID=2341:0043" in port[0]\
            or "VID:PID=2341:0043" in port[1]\
            or "VID:PID=2341:0043" in port[2]:
            print(port)
            print(port[0])
            print(port[1])
            print(port[2])

            #please note: it is not sure [0]
            #returned port[] is no particular order
            #so, may be [1], [2]
            return port[0]

def doAtExit():
    if serialUno.isOpen():
        serialUno.close()
        print("Close serial")
        print("serialUno.isOpen() = " + str(serialUno.isOpen()))

atexit.register(doAtExit)

unoPort = findArduinoUnoPort()
if not unoPort:
    print("No Arduino Uno found")
    sys.exit("No Arduino Uno found - Exit")

print("Arduino Uno found: " + unoPort)
print()

serialUno = serial.Serial(unoPort, 9600)
print("serialUno.isOpen() = " + str(serialUno.isOpen()))

while True:
    while (serialUno.inWaiting()==0):
        pass
    valueRead = serialUno.readline(500)
    print(valueRead)



In Arduino Uno side, just a simple program to repeatly call Serial.println() for testing.
AnalogInSerialOut.ino
const int analogIn = A0;
int analogVal = 0;

void setup() {
  Serial.begin(9600);
}

void loop() {

  analogVal = analogRead(analogIn);
  Serial.println(analogVal);
  delay(1000);
}

Friday, April 3, 2015

Find usb device of specified idVendor and idProduct in Python with PyUSB.

This simple example show how to find the USB device with specified idVendor and idProduct in Python with PyUSB, and print it's details.


- To install PyUSB, refer to the post "Download and Install PyUSB for Python 2 and 3".

- To know the Vendor ID and Product ID of your device, refer the post "Get idVendor and idProduct of your Arduino/USB devices".

- Enter the code, replace with your idVendor and idProduct. It run on both Python 2 and 3.

import usb.core
import usb.util

# find Arduino Uno
dev = usb.core.find(idVendor=0x2341, idProduct=0x0043)

# was it found?
if dev is None:
    raise ValueError('Device not found')

print(repr(dev))
print('VendorID  = 0x%04x'%dev.idVendor)
print('ProductID = 0x%04x'%dev.idProduct)
print
print(dev)


Example output of Arduino Uno rev 3, with idVendor=2341, idProduct=0043
<DEVICE ID 2341:0043 on Bus 002 Address 010>
VendorID  = 0x2341
ProductID = 0x0043
DEVICE ID 2341:0043 on Bus 002 Address 010 =================
 bLength                :   0x12 (18 bytes)
 bDescriptorType        :    0x1 Device
 bcdUSB                 :  0x110 USB 1.1
 bDeviceClass           :    0x2 Communications Device
 bDeviceSubClass        :    0x0
 bDeviceProtocol        :    0x0
 bMaxPacketSize0        :    0x8 (8 bytes)
 idVendor               : 0x2341
 idProduct              : 0x0043
 bcdDevice              :    0x1 Device 0.01
 iManufacturer          :    0x1 Error Accessing String
 iProduct               :    0x2 Error Accessing String
 iSerialNumber          :   0xdc Error Accessing String
 bNumConfigurations     :    0x1
  CONFIGURATION 1: 100 mA ==================================
   bLength              :    0x9 (9 bytes)
   bDescriptorType      :    0x2 Configuration
   wTotalLength         :   0x3e (62 bytes)
   bNumInterfaces       :    0x2
   bConfigurationValue  :    0x1
   iConfiguration       :    0x0 
   bmAttributes         :   0xc0 Self Powered
   bMaxPower            :   0x32 (100 mA)
    INTERFACE 0: CDC Communication =========================
     bLength            :    0x9 (9 bytes)
     bDescriptorType    :    0x4 Interface
     bInterfaceNumber   :    0x0
     bAlternateSetting  :    0x0
     bNumEndpoints      :    0x1
     bInterfaceClass    :    0x2 CDC Communication
     bInterfaceSubClass :    0x2
     bInterfaceProtocol :    0x1
     iInterface         :    0x0 
      ENDPOINT 0x82: Interrupt IN ==========================
       bLength          :    0x7 (7 bytes)
       bDescriptorType  :    0x5 Endpoint
       bEndpointAddress :   0x82 IN
       bmAttributes     :    0x3 Interrupt
       wMaxPacketSize   :    0x8 (8 bytes)
       bInterval        :   0xff
    INTERFACE 1: CDC Data ==================================
     bLength            :    0x9 (9 bytes)
     bDescriptorType    :    0x4 Interface
     bInterfaceNumber   :    0x1
     bAlternateSetting  :    0x0
     bNumEndpoints      :    0x2
     bInterfaceClass    :    0xa CDC Data
     bInterfaceSubClass :    0x0
     bInterfaceProtocol :    0x0
     iInterface         :    0x0 
      ENDPOINT 0x4: Bulk OUT ===============================
       bLength          :    0x7 (7 bytes)
       bDescriptorType  :    0x5 Endpoint
       bEndpointAddress :    0x4 OUT
       bmAttributes     :    0x2 Bulk
       wMaxPacketSize   :   0x40 (64 bytes)
       bInterval        :    0x1
      ENDPOINT 0x83: Bulk IN ===============================
       bLength          :    0x7 (7 bytes)
       bDescriptorType  :    0x5 Endpoint
       bEndpointAddress :   0x83 IN
       bmAttributes     :    0x2 Bulk
       wMaxPacketSize   :   0x40 (64 bytes)
       bInterval        :    0x1

Thursday, April 2, 2015

Python to plot graph of serial data from Arduino Uno analog input

It's a simple example to read analog input from Arduino Uno, send to PC via USB serial. In the PC side, running Python on Linux, plot the received serial graphically using matplotlib and drawnow library.




Arduino side:


AnalogInSerialOut.ino
const int analogIn = A0;
int analogVal = 0;

void setup() {
  Serial.begin(19200);
}

void loop() {

  analogVal = analogRead(analogIn);
  Serial.println(analogVal);
  delay(1000);
}

PC side running Python 2.7.6, plotArduino.py. It's the example code run in the demo video.
import serial
import matplotlib.pyplot as plt
from drawnow import *

values = []

plt.ion()
cnt=0

serialArduino = serial.Serial('/dev/ttyACM0', 19200)

def plotValues():
    plt.title('Serial value from Arduino')
    plt.grid(True)
    plt.ylabel('Values')
    plt.plot(values, 'rx-', label='values')
    plt.legend(loc='upper right')

#pre-load dummy data
for i in range(0,26):
    values.append(0)
    
while True:
    while (serialArduino.inWaiting()==0):
        pass
    valueRead = serialArduino.readline()

    #check if valid value can be casted
    try:
        valueInInt = int(valueRead)
        print(valueInInt)
        if valueInInt <= 1024:
            if valueInInt >= 0:
                values.append(valueInInt)
                values.pop(0)
                drawnow(plotValues)
            else:
                print "Invalid! negative number"
        else:
            print "Invalid! too large"
    except ValueError:
        print "Invalid! cannot cast"
    



Modified version of plotArduino.py:
- It seem that 19200 baud is not stable in my unit, so change to 9600. (Have to modify Arduino side also)
- Add some line to indicate status.
- Add atexit handling.
- Make it work on both Python 2 and 3.

import serial
import matplotlib.pyplot as plt
from drawnow import *
import atexit

values = []

plt.ion()
cnt=0

serialArduino = serial.Serial('/dev/ttyACM0', 9600)

def plotValues():
    plt.title('Serial value from Arduino')
    plt.grid(True)
    plt.ylabel('Values')
    plt.plot(values, 'rx-', label='values')
    plt.legend(loc='upper right')

def doAtExit():
    serialArduino.close()
    print("Close serial")
    print("serialArduino.isOpen() = " + str(serialArduino.isOpen()))

atexit.register(doAtExit)

print("serialArduino.isOpen() = " + str(serialArduino.isOpen()))

#pre-load dummy data
for i in range(0,26):
    values.append(0)
    
while True:
    while (serialArduino.inWaiting()==0):
        pass
    print("readline()")
    valueRead = serialArduino.readline(500)

    #check if valid value can be casted
    try:
        valueInInt = int(valueRead)
        print(valueInInt)
        if valueInInt <= 1024:
            if valueInInt >= 0:
                values.append(valueInInt)
                values.pop(0)
                drawnow(plotValues)
            else:
                print("Invalid! negative number")
        else:
            print("Invalid! too large")
    except ValueError:
        print("Invalid! cannot cast")




To install matplotlib, drawnow and pyserial:

for Python 2
$ sudo apt-get install python-matplotlib
$ sudo apt-get install python-pip
$ sudo pip install drawnow
$ sudo pip install pyserial

for Python 3
$ sudo apt-get install python3-matplotlib
$ sudo apt-get install python3-pip
$ sudo pip3 install drawnow
$ sudo pip3 install pyserial


Updated@2017-06-17:
It's a similarity example without using drawnow, tested on Raspberry Pi and PC/Ubuntu 17.04/Python 3.6 ~ Python run on Raspberry Pi (and PC running Ubuntu) to plot serial data from ESP8266/NodeMCU


Saturday, September 20, 2014

Firmata + Python/pyFirmata, control Arduino from Raspberry Pi

This post show steps to install pyFirmata, and also python-serial, on Raspberry Pi. Such that we can program Arduino Uno (with StandardFirmata sketch) using Python.

- Make sure you have Arduino IDE installed on Raspberry Pi.

- Install pyFirmata and python-serial, enter the command in Terminal.
$ sudo apt-get install python-pip python-serial
$ sudo pip install pyfirmata


To test your setup:

- Upload StandardFirmata sketch to your Arduino.
In Arduino IDE, click File > Examples > Firmata > StandardFirmata
Compile and upload the sketch to Arduino Uno.

- Try on Python IDLE
Start icon > Programming > IDLE to start Python
Enter the code:
>>> from pyfirmata import Arduino, util
>>> board = Arduino('/dev/ttyACM0')
>>> board.digital[13].write(1)
>>> board.digital[13].write(0)


Saturday, December 28, 2013

Install python-setuptools on Ubuntu

python-setuptools (setuptools) is a tools easy download, build, install, upgrade, and uninstall Python packages.

To download and install it, enter the command:

wget https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py -O - | sudo python

Friday, November 15, 2013

Communication between Arduino and Raspberry Pi (in Python)

This example show how to write a simple Python program on Raspberry Pi to get keyboard input and send to Arduino via USB. In Arduino, send back the received chars to Raspberry Pi, then print on screen in Pi side.



In this example, Raspberry Pi act as host and Arduino Due act as device, and connect with USB on Programming USB Port.

Python code in Raspberry Pi:
import serial
ser = serial.Serial('/dev/ttyACM1', 9600)

name_out = raw_input("Who are you?\n")
ser.write(name_out + "\n")
name_return = ser.readline()
print(name_return)

Code in Arduino side:
int pinLED = 13;
boolean ledon;

void setup() {
  Serial.begin(9600);
  pinMode(pinLED, OUTPUT);
  ledon = true;
  digitalWrite(pinLED, ledon = !ledon);
}
 
void loop() {
  if(Serial.available() > 0){
    Serial.print("Hello ");
    
    while(Serial.available()>0){
      char charIn = (char)Serial.read();
      Serial.print(charIn);
      if (charIn == '\n')
        break;
    }
    
    digitalWrite(pinLED, ledon = !ledon);
  }
}

Cross-post with my another blog: Hello Raspberry Pi

Wednesday, November 6, 2013

Getting Started with BeagleBone: Linux-Powered Electronic Projects With Python and JavaScript

Getting Started with BeagleBone
Getting Started with BeagleBone
Getting Started with BeagleBone: Linux-Powered Electronic Projects With Python and JavaScript

Many people think of Linux as a computer operating system, running on users' desktops and powering servers. But Linux can also be found inside many consumer electronics devices. Whether they're the brains of a cell phone, cable box, or exercise bike, embedded Linux systems blur the distinction between computer and device.

Many makers love microcontroller platforms such as Arduino, but as the complexity increases in their projects, they need more power for applications, such as computer vision. The BeagleBone is an embedded Linux board for makers. It's got built-in networking, many inputs and outputs, and a fast processor to handle demanding tasks. This book introduces you to both the original BeagleBone and the new BeagleBone Black and gets you started with projects that take advantage of the board's processing power and its ability to interface with the outside world.

Friday, July 26, 2013

Read online: Python Cookbook, Third Edition, By David Beazley and Brian K. Jones

Python Cookbook, Third Edition
By David Beazley 
and Brian K. Jones


Python Cookbook, Third Edition
Python Cookbook, Third Edition
If you need help writing programs in Python 3, or want to update older Python 2 code, this book is just the ticket. Packed with practical recipes written and tested with Python 3.3, this unique cookbook is for experienced Python programmers who want to focus on modern tools and idioms.

Inside, you’ll find complete recipes for more than a dozen topics, covering the core Python language as well as tasks common to a wide variety of application domains. Each recipe contains code samples you can use in your projects right away, along with a discussion about how and why the solution works.

Topics include:
- Data Structures and Algorithms
- Strings and Text
- Numbers, Dates, and Times
- Iterators and Generators
- Files and I/O
- Data Encoding and Processing
- Functions
- Classes and Objects
- Metaprogramming
- Modules and Packages
- Network and Web Programming
- Concurrency
- Utility Scripting and System Administration
- Testing, Debugging, and Exceptions
- C Extensions

link: http://chimera.labs.oreilly.com/books/1230000000393

Tuesday, March 26, 2013

Control Arduino LED using Python with GUI

This example demonstrate how to control Arduino LED using Python with GUI, using tkinter library.


#tkinter for Python 3.x
#Tkinter for Python 2.x

import serial
import time
import tkinter

def quit():
    global tkTop
    tkTop.destroy()

def setCheckButtonText():
    if varCheckButton.get():
        varLabel.set("LED ON")
        ser.write(bytes('H', 'UTF-8'))
    else:
        varLabel.set("LED OFF")
        ser.write(bytes('L', 'UTF-8'))

ser = serial.Serial('/dev/ttyACM1', 9600)
print("Reset Arduino")
time.sleep(3)
ser.write(bytes('L', 'UTF-8'))

tkTop = tkinter.Tk()
tkTop.geometry('300x200')

varLabel = tkinter.StringVar()
tkLabel = tkinter.Label(textvariable=varLabel)
tkLabel.pack()

varCheckButton = tkinter.IntVar()
tkCheckButton = tkinter.Checkbutton(
    tkTop,
    text="Control Arduino LED",
    variable=varCheckButton,
    command=setCheckButtonText)
tkCheckButton.pack(anchor=tkinter.CENTER)

tkButtonQuit = tkinter.Button(
    tkTop,
    text="Quit",
    command=quit)
tkButtonQuit.pack()

tkinter.mainloop()

For the code in Arduino side, refer to the post "Communicate with Arduino in Python programmatically".

Monday, March 25, 2013

serial.serialutil.SerialException: could not open port /dev/ttyACM0

If you try the steps in the post "Talk with Arduino Due in Python Shell" in Linux (Ubuntu in my setup). May be you will be complained with the error of:

serial.serialutil.SerialException: could not open port /dev/ttyACM0: [Errno 13] Permission denied: '/dev/ttyACM0'

Because your user account have no right to access the /dev/ttyACM0 port. You have to add your user account to the dialout group. Enter the command in Terminal:

$sudo usermod -a -G dialout <username>

After you plug in the usb cable, run the command (it need to be run every time plug-in):

$sudo chmod a+rw /dev/ttyACM0

serial.serialutil.SerialException
serial.serialutil.SerialException

Thursday, March 21, 2013

Talk with Arduino Due in Python Shell

With pySerial installed, it's easy to communicate with Arduino board in Python Shell.

Connect Arduino Due with sketch of former post downloaded.

For Python 2.x, enter the commands in Python Shell to turn ON/OFF LED on Arduino Due Board

>>>import serial
>>>ser = serial.Serial('/dev/ttyACM0', 115200)
>>>ser.write('H')
>>>ser.write('L')


For Python 3.x, the String in write() have to be casted to bytes.

>>>import serial
>>>ser = serial.Serial('/dev/ttyACM0', 115200)
>>>ser.write(bytes('H', 'UTF-8'))
>>>ser.write(bytes('L', 'UTF-8'))





Related:


Install pySerial on Ubuntu

To check if pySerial installed, open Python Shell, type the command:

>>>import serial

if error message returned, means pySerial not installed.

pySerial not installed
pySerial not installed with error

- To install pySerial on Ubuntu, download and unpack pyserial, open Terminal and change to the unpacked folder.

- To install for Python 2.x, type the command:

$sudo python setup.py install


- To install for Python 3.x, type the command:

$sudo python3 setup.py install

(To install the module for all users on the system, administrator rights (root) is required, run with sudo.)


pySerial installed
import serial with pySerial installed