Friday, July 17, 2020

Wio Terminal HMI Display for Raspberry Pi

Now you can use Wio Terminal as a HMI USB display for Raspberry Pi.



The wiki (https://wiki.seeedstudio.com/Wio-Terminal-HMI/) introduce how to use Wio Terminal as a HMI (Human Machine Interface) USB display for Raspberry Pi, Nvidia Jetson Nano, BeagleBone and even Odyssey X86J4105!

Sunday, June 21, 2020

Install Arduino IDE/Seeed SAMD Boards on Raspberry Pi OS, to program Wio Terminal on RPi

Steps to install Arduino IDE on Raspberry Pi 4/Raspberry Pi OS (32-bit), then add Seeed SAMD Boards; to program Seeed Wio Terminal on Raspberry Pi.



Install Arduino IDE (Linux ARM 32 bits) on Raspberry Pi/Raspberry Pi OS


Download Arduino IDE for Linux ARM 32 bits
https://www.arduino.cc/en/Main/Software

Basically follow the official guide to Install the Arduino Software (IDE) on Linux, but install by running ./install.sh with sudo.

$ sudo ./install.sh

After installed, I tested to program Wio Terminal without problem. No extra steps is needed to set serial port permission.


Install Seeed SAMD Boards to Arduino IDE, for Wio Terminal development


Open your Arduino IDE, click on File > Preferences,
and copy below url to Additional Boards Manager URLs:
https://files.seeedstudio.com/arduino/package_seeeduino_boards_index.json

Tools > Board > Board Manager,
Search Wio Terminal, install Seeed SAMD Boards.

reference: Get Started with Wio Terminal, more informative details and examples.

My first exercise for Wio terminal, simple detect button press and draw something on display:
#include <SPI.h>
#include <TFT_eSPI.h>

TFT_eSPI tft = TFT_eSPI();

int ptX = 50;
int ptY = 50;

/*  Some basic pre-defined example colours(16-bit) including in the LCD library:
#define TFT_BLACK       0x0000      //   0,   0,   0
#define TFT_NAVY        0x000F      //   0,   0, 128
#define TFT_DARKGREEN   0x03E0      //   0, 128,   0
#define TFT_DARKCYAN    0x03EF      //   0, 128, 128
#define TFT_MAROON      0x7800      // 128,   0,   0
#define TFT_PURPLE      0x780F      // 128,   0, 128
#define TFT_OLIVE       0x7BE0      // 128, 128,   0
#define TFT_LIGHTGREY   0xC618      // 192, 192, 192
#define TFT_DARKGREY    0x7BEF      // 128, 128, 128
#define TFT_BLUE        0x001F      //   0,   0, 255
#define TFT_GREEN       0x07E0      //   0, 255,   0
#define TFT_CYAN        0x07FF      //   0, 255, 255
#define TFT_RED         0xF800      // 255,   0,   0
#define TFT_MAGENTA     0xF81F      /* 255,   0, 255
#define TFT_YELLOW      0xFFE0      /* 255, 255,   0
#define TFT_WHITE       0xFFFF      /* 255, 255, 255
#define TFT_ORANGE      0xFDA0      /* 255, 180,   0
#define TFT_GREENYELLOW 0xB7E0      /* 180, 255,   0
ref: https://wiki.seeedstudio.com/Wio-Terminal-LCD-Basic/
*/

/*  basic graphical functions of the TFT LCD library on Wio Terminal.
    ref: https://wiki.seeedstudio.com/Wio-Terminal-LCD-Graphics/
drawPixel(int32_t x, int32_t y, uint32_t color);
drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t color);
drawFastHLine(int32_t x, int32_t y, int32_t w, uint32_t color); //Horizontal line
drawFastVLine(int32_t x, int32_t y, int32_t h, uint32_t color); //Verical line
drawRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color);
fillRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color);
drawCircle(int32_t x0, int32_t y0, int32_t r, uint32_t color);
fillCircle(int32_t x0, int32_t y0, int32_t r, uint32_t color);
drawEllipse(int16_t x0, int16_t y0, int32_t rx, int32_t ry, uint16_t color);
fillEllipse(int16_t x0, int16_t y0, int32_t rx, int32_t ry, uint16_t color);
drawTriangle(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint32_t color);
fillTriangle(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint32_t color);
drawRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, int32_t r, uint32_t color);
fillRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, int32_t r, uint32_t color);
drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uint32_t bg, uint8_t size)
drawString(const String& string, int32_t pptX, int32_t pptY);
fillScreen(uint32_t color);
*/

void updateLoc(String s){
  tft.drawPixel(ptX, ptY, TFT_WHITE);
  const String strLoc = s + " "+ (String)ptX + ":" + (String)ptY + "     ";
  Serial.println(strLoc);
  tft.drawString(strLoc, 100, 100);
}

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

  pinMode(WIO_KEY_A, INPUT_PULLUP);
  pinMode(WIO_KEY_B, INPUT_PULLUP);
  pinMode(WIO_KEY_C, INPUT_PULLUP);
  pinMode(WIO_5S_UP, INPUT_PULLUP);
  pinMode(WIO_5S_DOWN, INPUT_PULLUP);
  pinMode(WIO_5S_LEFT, INPUT_PULLUP);
  pinMode(WIO_5S_RIGHT, INPUT_PULLUP);
  pinMode(WIO_5S_PRESS, INPUT_PULLUP);

  tft.init();
  tft.setRotation(2);
  tft.fillScreen(TFT_LIGHTGREY);
  tft.fillRect(1, 1, 238, 318, TFT_BLACK);
  tft.fillTriangle(1, 1, 1, 11, 11, 1, TFT_BLUE);
  tft.fillTriangle(238, 318, 238, 308, 228, 318, TFT_RED);
  updateLoc("x");

}

 
void loop() {
  // put your main code here, to run repeatedly:
   if (digitalRead(WIO_5S_UP) == LOW) {
    Serial.println("5 Way Up");
    ptX++;
    updateLoc("^");
   }
   else if (digitalRead(WIO_5S_DOWN) == LOW) {
    Serial.println("5 Way Down");
    ptX--;
    updateLoc("v");
   }
   else if (digitalRead(WIO_5S_LEFT) == LOW) {
    Serial.println("5 Way Left");
    ptY--;
    updateLoc("<");
   }
   else if (digitalRead(WIO_5S_RIGHT) == LOW) {
    Serial.println("5 Way Right");
    ptY++;
    updateLoc(">");
   }
   else if (digitalRead(WIO_5S_PRESS) == LOW) {
    Serial.println("5 Way Press");
    updateLoc("@");
    tft.fillCircle(ptX, ptY, 5, TFT_ORANGE);
   }

   if (digitalRead(WIO_KEY_A) == LOW) {
    Serial.println("A Key pressed");
    ptX+=10;
    updateLoc("A");
    tft.fillCircle(ptX, ptY, 10, TFT_RED);
   }
   else if (digitalRead(WIO_KEY_B) == LOW) {
    Serial.println("B Key pressed");
    updateLoc("B");
    tft.fillCircle(ptX, ptY, 10, TFT_GREEN);
   }
   else if (digitalRead(WIO_KEY_C) == LOW) {
    Serial.println("C Key pressed");
    ptX-=10;
    updateLoc("C");
    tft.fillCircle(ptX, ptY, 10, TFT_BLUE);
   }
   delay(200);
}



to do...

This wiki introduce how to update the latest firmware for the Wireless Core Realtek RTL8720 on Wio Terminal, as well as installing all the dependent libraries for Wio Terminal to enable wireless connectivity.


Sunday, June 14, 2020

Friday, June 12, 2020

Python read Bluetooth Remote Shutter on Raspberry Pi


Here show how to read Bluetooth Remote Shutter using Python on Raspberry Pi. My testing unit named "AB Shutter3", with two buttons marked iOS and Android. Actually both buttons can trigger shutter of my Android phone.


Identify the input device of the remote shutter. In this step, lsinput is used to list input. Have to install input-utils.

$ sudo apt install input-utils

$ lsinput

and following commant:

$ ls /dev/input

List the input devices before and after the Bluetooth Remote Shutter to Raspberry Pi. Such that you can know the path to your BT shutter.

In my case, there are two new input devices added.
/dev/input/event5: "AB Shutter3 Consumer Control"
/dev/input/event6: "AB Shutter3 Keyboard"

But in my test, the /dev/input/event6 have NO event generated. So this exercise target to /dev/input/event5 only.

My Python exercise can run on Python 2 and 3, and evdev (https://python-evdev.readthedocs.io/en/latest/index.html) is needed. To install,

For Python3:
$ sudo pip3 install evdev

For Python2:
$ sudo pip install evdev

Python code, pyABS3.py
from evdev import InputDevice, categorize, ecodes

ABShutter3 = InputDevice('/dev/input/event5')

EV_VAL_PRESSED = 1
EV_VAL_RELEASED = 0
BTN_SHUTTER = 115

print(ABShutter3)

for event in ABShutter3.read_loop():
    if event.type == ecodes.EV_KEY:
        if event.value == EV_VAL_PRESSED:
            if event.code == BTN_SHUTTER:
                print('---')
                print('Shutter3 pressed')
                print(event)


It's found that both buttons on my shutter report the same code 115 (KEY_VOLUMEUP).


If you have such other similar device, you have to check the key code, you can use following code to list all event.

from evdev import InputDevice, categorize, ecodes

ABShutter3 = InputDevice('/dev/input/event5')

EV_VAL_PRESSED = 1
EV_VAL_RELEASED = 0
BTN_SHUTTER = 115

print(ABShutter3)

for event in ABShutter3.read_loop():
    if event.type == ecodes.EV_KEY:
        print(event)
        print(categorize(event))



Part II

After then, I borrow two more units from friends for testing. It's found that all 3 units output different combination of output.


-----------------------------------------------
Unit A:
event5: AB Shutter3 Consumer Control
event6: AB Shutter3 Keyboard

Big Button:
- event5 > KEY_VOLUMNUP

Small Button
- event5 > KEY_VOLUMNUP
-----------------------------------------------
Unit B:
event5: AB Shutter3          Consumer Control
event6: AB Shutter3          Keyboard

Big Button:
- event5 > KEY_VOLUMNUP
Small Button
- event6 > KEY_ENTER
- event5 > KEY_VOLUMNUP
-----------------------------------------------
Unit C:
event5: i Shutter Keyboard
event6: i Shutter3 Consumer Control

Big Button:
- event6 > KEY_VOLUMNUP
Small Button
- event5 > KEY_ENTER
-----------------------------------------------

Check the video:
(I capture the video on tab remotely via xrdp, so the response is slower.)


Testing Python script, pyShutter.py
# pyShutter.py
# Read Bluetooth Remote Shutter
# from /dev/input/event5 and /dev/input/event6
# filter for key down of ENTER and VOLUMNUP
#
# http://helloraspberrypi.blogspot.com/2020/06/detect-bluetooth-remote-shutter-ab.html
#
# Work on Python 3.5+
# For Reading events from multiple devices
# read https://python-evdev.readthedocs.io/en/latest/tutorial.html

from evdev import InputDevice, categorize, ecodes
import asyncio

Shutter5 = InputDevice('/dev/input/event5')
Shutter6 = InputDevice('/dev/input/event6')

EV_VAL_PRESSED = 1
EV_VAL_RELEASED = 0
KEY_ENTER = 28
KEY_VOLUMNUP = 115

print(Shutter5)
print(Shutter6)
print('=== Start ===')

async def print_events(device):
                
    async for event in device.async_read_loop():
        if event.type == ecodes.EV_KEY:
            if event.value == EV_VAL_PRESSED:
                if event.value == EV_VAL_PRESSED:
                    if event.code == KEY_ENTER:
                        print('<ENTER> Pressed')
                    elif event.code == KEY_VOLUMNUP:
                        print('<VOLUMNUP> Pressed')
                print(device.path, categorize(event), sep=': ')          
                print('---')

for device in Shutter5, Shutter6:
    asyncio.ensure_future(print_events(device))

loop = asyncio.get_event_loop()
loop.run_forever()



Python tkinter to detect key event

Python exercise to detect key event, for Python3 + tkinter run on Raspberry Pi OS

import tkinter as tk

def key_fun(event):
    print(event)
    key_press = event.keysym
    print(key_press)

command = tk.Tk()
command.bind_all('<Key>', key_fun)
command.mainloop()


Thursday, May 28, 2020

NEW Raspberry Pi OS update

NEW Raspberry Pi OS update (May 2020)



visit: http://rpf.io/raspberrypios

Just announced: 8GB Raspberry Pi 4, 64-bit Raspberry Pi OS

Raspberry Pi Blog announced 8GB Raspberry Pi 4 on sale now at $75, and also introduced the early beta 64-bit Raspberry Pi OS.

source:
~ Raspberry Pi Blog - 8GB Raspberry Pi 4 on sale now at $75
~ You can find a link to the new 64-bit image, and some important caveats, in this forum post.

You can also read all about it in The MagPi magazine issue 94. Include download link for free PDF version.
https://magpi.raspberrypi.org/issues/94


Monday, May 25, 2020

Python to check CPUs speed of Raspberry Pi

In Terminal, you can use this command to get the current CPU current frequency:

$ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq

where cpu0 can be cpu0~3 for Raspberry Pi 4B. You can enter this command to get frequency of all 4 CPUs.

$ cat /sys/devices/system/cpu/cpu[0-3]/cpufreq/scaling_cur_freq


Here is my Python exercise to display speeds of CPUs on Raspberry Pi 4B. It's found that running this script will make the CPUs running in higher speed. For demonstration, I insert a delay and repeat read the CPUs speed to show the effect.


checkCPUs.py
import sys
import subprocess
import time

cmd = "cat /proc/device-tree/model"
model = subprocess.check_output(cmd, shell=True).decode("utf-8")
print(model)
print("Python: " + sys.version)
print()

def readCPUs():
    #cmd = "find /sys/devices/system/cpu/cpu[0-3]/cpufreq/scaling_cur_freq -type f | xargs cat"
    cmd = "cat /sys/devices/system/cpu/cpu[0-3]/cpufreq/scaling_cur_freq"
    freqs = subprocess.check_output(cmd, shell=True).decode("utf-8")
    freqList = freqs.splitlines()

    for index, i in enumerate(freqList):
        curFreq = float(i)
        print("CPU" + str(index) + " : " + str(curFreq/1000000) + " GHz")
        
time.sleep(3)
readCPUs()
readCPUs()
readCPUs()


Python to check system info and status

Python script to check system info and status, for Python3. To print model of your board, Python version, IP, temperature, CPU usage, memory usage and disk usage.

checkit.py
import sys
import subprocess

cmd = "cat /proc/device-tree/model"
model = subprocess.check_output(cmd, shell=True).decode("utf-8")
print(model)

print("Python: " + sys.version)
cmd = "hostname -I"
IP = subprocess.check_output(cmd, shell=True).decode("utf-8")
print("IP: " + IP)

cmd = "vcgencmd measure_temp"
temp = subprocess.check_output(cmd, shell=True).decode("utf-8")
print(temp)

cmd = "top -bn1 | grep load | awk '{printf \"CPU Load: %.2f\", $(NF-2)}'"
CPU = subprocess.check_output(cmd, shell=True).decode("utf-8")
print(CPU)

cmd = "free -m | awk 'NR==2{printf \"Memory usage: %s/%s MB %.2f%%\", $3,$2,$3*100/$2 }'"
MemUsage = subprocess.check_output(cmd, shell=True).decode("utf-8")
print(MemUsage)

cmd = "df -h | awk '$NF==\"/\"{printf \"Disk usage: %d/%d GB %s\", $3,$2,$5}'"
DiskUsage = subprocess.check_output(cmd, shell=True).decode("utf-8")
print(DiskUsage)



Sunday, May 24, 2020

How to check Raspberry Pi 4B reversion 1.2

When the first time Raspberry Pi 4B released, it is a bug in USB-C power supply circuitry. If you use the official USB-C power supply, it should be no problem. If you use other cables (marked with an "e"), it may be have compatibility problem.

It's fixed in Raspberry Pi 4B rev 1.2. So, how can you identify the reversion of your board? Use any of the commands:

$ pinout


It is shown V1.2 in the output. And also shown c03112 in Revision column, you can check Raspberry Pi revision codes here.

or use the command:

$ cat /proc/device-tree/model


or:

$ cat /proc/cpuinfo

Revision is listed c03112.



You can also check it visually, refer to cnx-software post, Raspberry Pi 4 Rev 1.2 Fixes USB-C Power Issues, Improves SD Card Resilience.


Saturday, May 23, 2020

Python to control Raspberry Pi Camera

It's a simple Python script run on Raspberry Pi/Raspbian to perform simple control of camera, start preview, stop preview, and capture photo.

It run with Python3.

import sys
from tkinter import *
import picamera
from pkg_resources import require
import time

#event callback functions
def evStartPreviewBtnPressed():
    print("Start Preview")
    camera.start_preview()

def evStopPreviewBtnPressed():
    print("Stop Preview")
    camera.stop_preview()

def evCaptureBtnPressed():
    print("Capture")
    timeStamp = time.strftime("%Y%m%d-%H%M%S")
    targetPath="/home/pi/Desktop/img_"+timeStamp+".jpg"
    print(targetPath)
    camera.capture(targetPath)

print(sys.version)
print(require('picamera'))


#Prepare camera
camera = picamera.PiCamera()


root = Tk()
root.geometry("600x360")
root.wm_title("Hello")
#root.configure(bg = "#909090")

labelSys = Label(root, text=sys.version, justify=LEFT)
labelSys.grid(row=0, columnspan=2, sticky=W)
labelPiCameraVer = Label(root, text=require('picamera'), justify=LEFT)
labelPiCameraVer.grid(row=1, columnspan=2, sticky=W)
                         

btnStartPreview = Button(root, text="Start Preview",
                         command=evStartPreviewBtnPressed)
btnStopPreview = Button(root, text="Stop Preview",
                        command=evStopPreviewBtnPressed)
btnStartPreview.grid(row=2, column=0, sticky=W+E)
btnStopPreview.grid(row=2, column=1, sticky=W+E)

btnCapture = Button(root, text="Capture",
                    command=evCaptureBtnPressed)
btnCapture.grid(row=3, columnspan=2, sticky=W+E)


root.mainloop()

#close tasks
camera.close()

With Microsoft's Remote Desktop on Android device, it can be run remotely. The camera preview will be displayed on local screen.


xredp have to be installed in Raspberry Pi, with command:
$ sudo apt-get install xrdp

This video show how it run on Raspberry Pi 3 with Waveshare 4" HDMI LCD, run it on Android phone with Remote Desktop app. The local mounted display (4" HDMI LCD) is used as viewfinder.


Remark:
If you run the script locally, the preview will cover the GUI, but you can still click on it. Click the original position of the Stop Preview button to close the preview.


NOT WORK on High Quality Camera

Once I received High Quality Camera and tested on it, the script fail when capture continuously. Then I make a simple script to take photos using RPi Camera Module, work on v2.1, but also faile on High Quality Camera with "picamera.exc.PiCameraRuntimeError: No data received from sensor."


What's wrong on the script? or my Raspberry Pi High Quality Camera defected?

Tested on:
- Raspberry Pi 3B+
- Update Raspberry Pi OS
- Python 3.7.3
- picamera 1.13

doCappp.py
import picamera
import time

with picamera.PiCamera() as camera:
    camera.start_preview()
    for i in range(5):
        camera.resolution = (1280, 720)
        time.sleep(1)
        filename = 'imageA%02d.jpg' % i
        camera.capture(filename)
        print('Captured %s' % filename)
    time.sleep(7)
    
    print("End")
    camera.stop_preview()
    time.sleep(1)
    print("End End")
    camera.close()
    print("End End End")


Tuesday, May 19, 2020

pinout command, to query Raspberry Pi GPIO pin-out information.

In update Raspbian, the pinout command was added. It's a funny and informative utility for querying Raspberry Pi GPIO pin-out information.

$ pinout


Related:
How to check Raspberry Pi 4B reversion 1.2, it provide more option to check your board version.


Check model and revision of your Raspberry Pi board

With the upadte Raspbian, you can read model and rev. of your Raspberry Pi board in /proc/device-tree/model. Enter the command in terminal:

cat /proc/device-tree/model


Related:
How to check Raspberry Pi 4B reversion 1.2, it provide more option to check your board version.

Friday, April 17, 2020

Sipeed MaixCube – All-in-One AI Development Platform Based on K210 (RISC-V)

Sipeed MaixCube is an all-in-one development platform based on the M1n module which is powered by the Kendryte K210 core. It is equipped with a camera, TF card slot, user buttons, TFT display, lithium battery, speaker, microphone and an expansion interface. This provides a great platform for everyone to start learning about AI development.


Features

  • All-in-One Platform with Rich Peripherals
  • K210 RISC-V 64-bit Dual-Core CPU for Powerful AI Applications
  • Computing Power up to 1TOPS for Heavy Machine Vision Applications
  • Built-in FPU, KPU, FFT Hardware Acceleration Units
  • Built-in APU for High-Quality Audio Processing


source: https://www.seeedstudio.com/Sipeed-Maix-Cube-p-4553.html

Thursday, March 19, 2020

Thursday, January 9, 2020