Tag Archives: raspberry

Portable Logitech Media Server again

See post: https://www.henriaanstoot.nl/2014/04/10/portable-squeeze-server/

In the past i’ve used a home build Logitech Squeezebox server (as it was called then), Picore player and tried volumio.
Picore player has been sitting in my livingroom for ages, but was converted to a Node-Red Dashboard and recently Home Assistant Dashboard. (Has been a dasticz daskboard also)

Today i build another version, smaller and with a screen.
Why? .. because of being ‘offline’ or ‘offgrid’ on our holidays.
The car we are driving only has a Aux input.

Most of the installation is as mentioned on:
https://docs.picoreplayer.org/projects/add-a-display/

I edited  /opt/bootsync.sh
to get /dev/sda1 mounted persistent
use pcp br after editing.

Default user/pass : tc piCore

Controlling the thing is via touch or a app on my phone using wifi hotspot.

  • Audio cable 3.5mm
  • Raspberry 3
  • Large usb thumbdrive
  • 3.5inch RPi Display – 480×320 Pixel – XPT2046 Touch Controller
  • car cigarette lighter adapter for power

PiCore uses below alliases

ceChange directory to /mnt/mmcblk0p2/tce
ceoChange directory to /mnt/mmcblk0p2/tce/optional
m1Mount the boot partition /mnt/mmcblk0p1
m2Mount the second partition /mnt/mmcblk0p2
c1Change directory to /mnt/mmcblk0p1
c2Change directory to /mnt/mmcblk0p2
vicfgEdit configuration file config.txt using vi
vicmdEdit boot file cmdline.txt using vi
u1Unmount the boot partition /mnt/mmcblk0p1
u2Unmount the second partition /mnt/mmcblk0p2

Shutting down piCore is done by cutting the power, due to everything being mounted readonly. EXEPT
When you are using LMS server installation, which uses a database.
But there is a tweak for a shutdown button.

I’m using GPIO 16 because i’ve got a screen connected.
Active LOW, means you have to connect a pushbutton/switch between GND and GPIO pin. (nearest Vcc OR Gnd)

Retropi handheld

I’ve got a retro-pi running for some time, now .. posting a little movie.
The gamehat i’ve got a week now.

Retropi met Darish Zone King Image

  • 512GB
  • 23000 games
  • 50 systems

Own hacks on this system:

  • Added dos emulator
  • Added DOS games
  • Added Amiga demos menu entry
  • Changed Font sized and look

I’ve got a bigben controller which i can connect to the Raspberry USB .

375403 (600×315)

A sms gateway

Sms form

Made a generic sms sender, for check_mk monitoring + sending password of accounts.
You can send sms by filling in a form, or using a url like:

http://smsgateway.local:8080/sms/0612341234/Message%20met%20spaties

It uses a Raspberry and a sim800L module.

Fritzing schematic
At work in a corner near a window (3d printed case)

Remove pin from simcard fix:

sudo minicom -b 115000 -o -D /dev/serial0

 AT+CPIN?
+CPIN: SIM PIN

AT+CPIN=0000
OK

AT+CLCK=”SC”,0,”0000″
OK

AT+CPIN?
+CPIN: READY 

Cron

@reboot sh /home/pi/launcher.sh 

Launcher

cat /home/pi/launcher.sh
#!/bin/bash
cd /home/pi
while true; do
/usr/bin/python newapi.py
done

newapi.py (uses flask)

import serial
import RPi.GPIO as GPIO     
import os, time
import sys

from flask import Flask, render_template, request
app = Flask(__name__)

from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField, SubmitField, TextAreaField
from wtforms.validators import DataRequired

from flask import render_template

app.config['SECRET_KEY'] = 'you-will-never-guess'

class FormForm(FlaskForm):
    telnumber = StringField('telnumber', validators=[DataRequired()])
    messagepart = TextAreaField('Text', render_kw={"rows": 5, "cols": 20})
    submit = SubmitField('Send Sms')
 
@app.route("/sms/<number>/<message>")
def action(number, message):
        num = number.encode() 
        mes = message.encode() 
	GPIO.setmode(GPIO.BOARD)   
	# Enable Serial Communication
	port = serial.Serial("/dev/serial0", baudrate=9600, timeout=1)

	# Transmitting AT Commands to the Modem
	# '\r\n' indicates the Enter key
	port.write('AT'+'\r\n')
	rcv = port.read(10)
	print rcv
	time.sleep(1)
	#port.write('ATE0'+'\r\n')      # Disable the Echo
	#rcv = port.read(10)
	#print rcv
	#time.sleep(1)
	port.write('AT+CMGF=1'+'\r\n')  # Select Message format as Text mode
	rcv = port.read(10)
	print rcv
	time.sleep(1)
	port.write('AT+CNMI=2,1,0,0,0'+'\r\n')   # New SMS Message Indications
	rcv = port.read(10)
	print rcv
	time.sleep(1)
	port.write('AT+CSCS="GSM"'+'\r\n')   
	rcv = port.read(10)
	print rcv
	time.sleep(1)
	# Sending a message to a particular Number
	port.write('AT+CMGS="'+num+'"\r\n')
	rcv = port.read(10)
	print rcv
	time.sleep(1)
	port.write(mes+'\r\n')  # Message
	rcv = port.read(10)
	print rcv
	port.write("\x1A") # Enable to send SMS
	for i in range(10):
	    rcv = port.read(10)
	    print rcv
        return 'OK'
@app.route("/form")
def form():
    form = FormForm()
    return render_template('web.html', title='Web Sms', form=form)
@app.route('/data', methods = ['POST', 'GET'])
def data():
    if request.method == 'GET':
        return "The URL /data is accessed directly. Try going to '/form' to submit form"
    if request.method == 'POST':
  
        telnumber = request.form['telnumber']
        messagepart = request.form['messagepart']
        num = telnumber.encode() 
        mes = messagepart.encode()
	GPIO.setmode(GPIO.BOARD)   
	# Enable Serial Communication
	port = serial.Serial("/dev/serial0", baudrate=9600, timeout=1)
	# Transmitting AT Commands to the Modem
	# '\r\n' indicates the Enter key
	port.write('AT'+'\r\n')
	rcv = port.read(10)
	print rcv
	time.sleep(1)
	#port.write('ATE0'+'\r\n')      # Disable the Echo
	#rcv = port.read(10)
	#print rcv
	#time.sleep(1)
	port.write('AT+CMGF=1'+'\r\n')  # Select Message format as Text mode
	rcv = port.read(10)
	print rcv
	time.sleep(1)
	port.write('AT+CNMI=2,1,0,0,0'+'\r\n')   # New SMS Message Indications
	rcv = port.read(10)
	print rcv
	time.sleep(1)
	port.write('AT+CSCS="GSM"'+'\r\n')   
	rcv = port.read(10)
	print rcv
	time.sleep(1)
	# Sending a message to a particular Number
	port.write('AT+CMGS="'+num+'"\r\n')
	rcv = port.read(10)
	print rcv
	time.sleep(1)
	port.write(mes+'\r\n')  # Message
	rcv = port.read(10)
	print rcv
	port.write("\x1A") # Enable to send SMS
	for i in range(10):
	    rcv = port.read(10)
	    print rcv
       
        return '<a href="/form">Nog een SMS sturen</a>'
@app.route("/checkmk")
def checkmk():
        # Enable Serial Communication
        port = serial.Serial("/dev/serial0", baudrate=9600, timeout=1)
   
        port.write('AT'+'\r\n')
        rcv1 = port.read(30)
        time.sleep(1)

        port.write('AT+CPAS'+'\r\n')
        rcv2 = port.read(30)        
        time.sleep(1)
    
        port.write('AT+CGREG?'+'\r\n')
        rcv3 = port.read(30)
        time.sleep(1)
    
        port.write('AT+CGATT?'+'\r\n')
        rcv4 = port.read(30)
        time.sleep(1)
    
        port.write('AT+CSQ'+'\r\n')
        rcv5 = port.read(30)
        time.sleep(1)

        return 'OK of niet' + rcv1 + rcv2 + rcv3 + rcv4 + rcv5
if __name__ == "__main__":
   app.run(host='0.0.0.0', port=8080, debug=True)

Lidar POC for Vincent

Using Python, Raspberry, a lidar module, a servo, display .. and a 3Dprinted holder.

Proof of concept was to see if it was easy to implement a lidar radar for boat navigation.

#!/usr/bin/env python
import math
import random
import pygame
from pygame.locals import *
import time
import serial
import pigpio

GPIO = 18
ser = serial.Serial("/dev/ttyUSB0", 115200)

pi = pigpio.pi()
distance = 0
pygame.init()
screen = pygame.display.set_mode((480, 320))
while True:
        screen.fill((0,0,0))
        pygame.draw.circle(screen, (0,128,0), (240,320), 100,1)
        pygame.draw.circle(screen, (0,128,0), (240,320), 200,1)
        pygame.draw.circle(screen, (0,128,0), (240,320), 300,1)
        for deze in range(10,170,5):
            count = ser.in_waiting
            if count > 8:
                    recv = ser.read(9)
                    ser.reset_input_buffer()
                    if recv[0] == 'Y' and recv[1] == 'Y': # 0x59 is 'Y'
                        low = int(recv[2].encode('hex'), 16)
                        high = int(recv[3].encode('hex'), 16)
                        global distance
                        distance = low + high * 256
            res = distance
            #print res
            x =  res * math.cos(math.radians(deze))
            y =  res * math.sin(math.radians(deze))
            xreal = x + 240
            yreal = 320 - y
            pygame.draw.line(screen, (0, 255, 0), (240, 320), (xreal, yreal))

            pygame.time.wait(15)
            pygame.display.flip()
            #print(res)
            pi.set_servo_pulsewidth(GPIO, deze * 11 + 500)
            time.sleep(0.2)
        screen.fill((0,0,0))
        pygame.draw.circle(screen, (0,128,0), (240,320), 100,1)
        pygame.draw.circle(screen, (0,128,0), (240,320), 200,1)
        pygame.draw.circle(screen, (0,128,0), (240,320), 300,1)
        for deze in range(170,10,-5):
            count = ser.in_waiting
            if count > 8:
                    #print count
                    recv = ser.read(9)
                    ser.reset_input_buffer()
                    if recv[0] == 'Y' and recv[1] == 'Y': # 0x59 is 'Y'
                        low = int(recv[2].encode('hex'), 16)
                        high = int(recv[3].encode('hex'), 16)
                        global distance
                        distance = low + high * 256
            res = distance
            x =  res * math.cos(math.radians(deze))
            y =  res * math.sin(math.radians(deze))
            xreal = x + 240
            yreal = 320 - y
            pygame.draw.line(screen, (0, 255, 0), (240, 320), (xreal, yreal))
            pygame.time.wait(15)
            pygame.display.flip()
            pi.set_servo_pulsewidth(GPIO, deze * 11 + 500)
            time.sleep(0.2)
#pi.set_servo_pulsewidth(GPIO, 0)

Pressure Lab

For measuring pressure in fermentation containers, I designed a pressure sensor which could be wireless connected to a fermentation container.
The sensor would transmit the values to a Raspberry which was configured as a Access Point and would store the measurements and generated graphs using Grafana.

Raspberry with RealtimeClock
RTC on raspberry

3D printed holder, designed in blender. Holds battery prints and has little handle to lift from container

Nodes config:

Esp configuration, connect with micro-usb
Flashing with linux

esptool.py -p /dev/ttyUSB0  write_flash 0x00000  ESP_Easy_mega-20190311_normal_ESP8266_4M.bin

Make a connection with the ESP Access point

Connect esp with a power source.
Look for a AP with ESP_Easy_0

Use password “configesp” to connect

Start you browser and enter http://192.168.4.1

In wifi wizard setup select “pressurespot”
Enter password “pressurespot”

Press connect

Wait 20s and look in the raspberry logs which IP the ESP got.

Connect laptop/mobile to wifi “pressurespot”and connect

Enter found IP from ESP in your browser.

Proceed to main config

Main setting table, set the following

  • Unit name & number + append
  • SSID and WPA key pressurespot
  • Client IP block level allow all
  • Press submit

Press controller tab

Press first edit button and set following
– Protocol: domoticz http
Next set
– Controller IP : 10.42.0.1
– Toggle enabled and press submit

Resulting in:

Next we got to Hardware

I2C interface switch GPIO-4 and GPIO-5

  • GPIO – SDA: GPIO-4 (D2) change to GPIO-5 (D1)
  • GPIO – SCL: GPIO-5 (D1) change to GPIO-4 (D2)
  • Press “Submit”

Devices TAB

Press edit, and select device “Environment – BMx280” from the pulldown menu.

Next, set the following

  • Name: pressure
  • Enable on
  • I2C address : 0x76 ( Is there is no 0x76 of 0x77 .. do a i2c scan on the next tab )
  • Send to controller , mark this
  • IDX: give this the number you had given this node (this is the one you have to use in domoticz )
  • interval 10Seconds
  • and press submit

In the Devices tab, you should be able to see the sensor with the values (Temperature and pressure)

No values? Do a i2c scan and/or reboot ESP ( You can find these in the tools tab)

Tools TAB

Press I2C scan, when seeing a address like 0x76 or 0x77 use this in previous tabs.
Still nothing, even after reboot? Maybe faulty hardware?

Everything okay? Back to the config tab

We are going to set the sleep mode.
Warning ! .. when setting this it is hard to get into the config pages again.
ESP will startup, connect to wifi, send values and goes to sleep again.

At the bottom set: Sleep awake time 1 sec

Buttons on the raspberry / pressurespot

Red button :

  • Less than 3 seconds is reboot
  • Longer than 3 seconds is shut down
    • Charger can be removed, when the green light is off

Led lights on the sensors

  • Red light (R2; constant): battery is charging
  • Blue light (R1; constant): battery is full
  • Blue light (R1; constant) & red light (R2; blinking): trying to charge, but no battery connected

Add shutdown script to /etc/rc.local

python /usr/local/bin/power-switch.py &amp;

/usr/local/bin/power-switch.py

#!/usr/bin/python
import threading, subprocess
import RPi.GPIO as GPIO
def shutdown():
    subprocess.call('sudo shutdown -h now', shell=True)
def edge_detected(pin):
    if GPIO.input(pin):
        t.cancel()
        subprocess.call('sudo reboot', shell=True)
    else:
        t.start()
if __name__ == '__main__':
    try:
        GPIO.setmode(GPIO.BOARD)
        GPIO.setup(5, GPIO.IN)
        GPIO.add_event_detect(5, GPIO.BOTH, callback=edge_detected, bouncetime=10)
        t = threading.Timer(3.0, shutdown)
        while True:
            pass
    finally:
        GPIO.cleanup()

/usr/local/bin/ledoff.py

#!/usr/bin/python
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(18,GPIO.OUT)
GPIO.output(18,GPIO.LOW)

/usr/local/bin/ledon.py

#!/usr/bin/python
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(18,GPIO.OUT)
GPIO.output(18,GPIO.HIGH)

nmcli device wifi hotspot ssid pressurespot password pressurespot

 /etc/NetworkManager/system-connections/Hotspot-1

[connection]
id=Hotspot-1
uuid=c2c05528-63f9-44c7-93ce-264187a45086
type=wifi
permissions=
timestamp=1553708934

[wifi]
hidden=true
mac-address=B8:27:EB:7F:D5:E7
mac-address-blacklist=
mode=ap
seen-bssids=B8:27:EB:7F:D5:E7;
ssid=pressurespot

[wifi-security]
group=ccmp;
key-mgmt=wpa-psk
pairwise=ccmp;
proto=rsn;
psk=pressurespot

[ipv4]
dns-search=
method=shared

[ipv6]
addr-gen-mode=stable-privacy
dns-search=
method=ignore

/usr/bin/servicecheck.sh (in rc.local and crontab root user – every minute

#!/bin/bash
nmcli connection show  | grep "Hotspot-1           c2c05528-63f9-44c7-93ce-264187a45086  802-11-wireless  wlan0" &gt;/dev/null &amp;&amp; touch /tmp/wlan || rm -f /tmp/wlan
for f in influx domoticz telegraf grafana mosquitto ; do
pgrep $f &gt;/dev/null &amp;&amp; touch /tmp/$f || rm -f /tmp/$f
done
count=$(ls  /tmp/influx /tmp/domoticz /tmp/telegraf /tmp/grafana /tmp/mosquitto /tmp/wlan | wc -l)
if [ $count -eq 6 ]  ; then
/usr/local/bin/ledon.py
exit 0
fi

for timer in {1..10} ; do
/usr/local/bin/ledon.py
sleep 1

/usr/local/bin/ledoff.py
sleep 1
done

Rest services to be installed on Raspberry

At the moment the raspberry uses domoticz between the Mqtt broker (Mosquitto) and the database (Influx)
Data wil be displayed using grafana.

tail -f /var/log/syslog shows which ip to which ESP
DHCPACK(wlan0) 10.42.0.104 cc:50:e3:c4:96:61 lab-
DHCPACK(wlan0) 10.42.0.181 cc:50:e3:c4:8d:73 lab-4
DHCPACK(wlan0) 10.42.0.186 cc:50:e3:c4:9b:ef lab-1

Configuring the raspberry

Install influx and grafana

First we add Influx repositories to apt:

wget -qO- https://repos.influxdata.com/influxdb.key | sudo apt-key add -
source /etc/os-release
echo "deb https://repos.influxdata.com/debian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/influxdb.list

Update apt with the new repo & install.

sudo apt update && sudo apt install -y influxdb

Then start the influxdb service and set it to run at boot:

sudo systemctl enable influxdb --now

Again we need to add the Grafana packages to apt:

wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add -
echo "deb https://packages.grafana.com/oss/deb stable main" | sudo tee /etc/apt/sources.list.d/grafana.list

We can now update and install the binaries:

sudo apt update && sudo apt install -y grafana

Then simply enable the service and set to run at boot:

sudo systemctl enable grafana-server.service --now

Now we can check that grafana is up by loading it in a browser: http://10.42.0.1:3000. If so, you can log in with the username and password = admin and set a new admin password.

Install mosquitto

sudo apt install mosquitto mosquitto-clients

Install domoticz using below command

<code><strong>curl -sSL install.domoticz.com | sudo bash</strong></code>

Under hardware add MQTT server adress 127.0.0.1

Add virtual sensors to domoticz.

Click hardware and create virtual sensor, lab with sensornumber. Sensor type is Temp+Baro.

When looking at devices you will see the virtual devices.

Here you can see if data is coming from the ESP’s

Pushing the data into Influxdb:

Goto settings > more options > data push > influxdb

Add temperature

  • Device name: lab* (lab plus unit number)
  • Value to send: temperature
  • Target type: direct (NOTE screenshot below is wrong)
  • press add

Add barometer

  • Device name: lab* (lab plus unit number)
  • Value to send: Barometer
  • Target type: direct (NOTE screenshot below is wrong)
  • press add

Configure Grafana

Go with your browser to http://10.42.0.1 when connected to the rpi access point

Goto settings and data sources, add influxdb with source http://localhost:8086
Goto dashboard and create a new one.

Data source is influx, select A Barometer
And the IDX that was used in configuring the ESP
Axes: Units in millibars, above example had temperature, for both Baro and Temp in one graph.
Select null value as connected

TODO

Telegraf/mosquito
Services in domoticz
Rpi status display
Sensor test / monitor

Portable Squeeze Server

Update : https://www.henriaanstoot.nl/2022/05/26/portable-logitech-media-server-again/


Below is a picture of my mobile LMS server i used in my car.
I only had radio and a CD player, i’m not a radio man .. folk, pipes and audiobooks


At the time i was working for Dutch Railways, imagine me walking with this blinky leds thingy, though the railway station …

It consisted of a dual port usb charger, a usb hub to power the drive, the rpi wasn’t strong enough. Thumbdrives where small in capacity, so i had to use a spinning disk harddrive.
It was only a raspberry 1, in a case i had designed and lasercutted at Fablab Utrecht.

Now you can get rid of the Usb hub and harddrive using a small but with large capacity sdcards.

I could charge the thing in my car, and when i got home, it would connect to my home wifi network, sync-ed my MP3’s and turn off.