Opzet DVB-S Print voor Raspberry PI
[Opzet DVB-S cube PE2JKO] Doel was een compacte DVB-S zender te maken welke te bedienen is zonder keyboard/muis/laptop gebruik makend van opzet printje van Robert PA0RJV welke [HIER] beschreven is. Concepten welke hier gebruikt worden zijn:
1) UglyDATV van Evariste
2) DVB-S IQ modulator opzet printje voor Raspberry PI B+
4) Avalpa en Python
5) ADF4351 VCO kant en klaar PCB
6) Besturing ADF4351 door middel van Atmega16 , 2 regelig display met rotary encoder gemaakt in Bascom.
7) 2x Raspberry PI (model B+ en Model 2) met RaspiCamera aangesloten op Raspberry PI 2.
Er wordt gebruik gemaakt van 2 Raspberry PIś, een RPI model B+ voor de IQ modulator en een Raspberry PI 2 voor de opwekking van de Stream en besturing van TFT scherm en buttons. Voor de VCO wordt gebruik gemaakt van een ADF4351, regelbaar tussen 35 Mhz en 4400 Mhz. Beide raspberry PIś praten via ethernet kabel met elkaar. De Raspberry PI B+ met de IQ modulator hoeft in principe weinig te doen, hij moet gaan luisteren op poort 1234 van multicast address 239.0.0.1 en moet de UglyDATV encoder starten met de juiste parameters qua Samplerate en FEC, daarnaast moet hij in een file aangeven welke samplerate er opgestart is. Dat wordt telkens door de Raspberry PI 2 gekopieerd naar zijn eigen directory. Op de Raspberry PI 2 is een TFT scherm aangesloten met een opsteekprintje wat op de GPIO header komt van de Raspberry PI, op connector X3 komen een stuk of 4 GPIO aanslutingen naar buiten en daar sluit ik de buttons ( maak/verbreek ) op aan. Het TFT scherm wordt aangestuurd door Python script, eigenlijk kijkt hij in 3 files op de eigen Raspberry PI 2, wat elke seconde wordt ververst. In 1 file staat de gewenste SampleRate, in een ander file staat de status ( welke samplerate is er opgestart opd e Raspberry PI model B+ met IQ modulator) en 3e file is de gewenste stream. Dan is er een apart programma welke ook in Python is geschreven wat de buttons bedient. Dit script zorgt ervoor dat er een stream wordt opgestart op de eigen Raspberry PI 2 of eventueel van een externe computer. Zodra op de eerste button wordt gedrukt wordt er in een file een string weg geschreven bv ¨Camera¨ of ¨Testbeeld¨ etc, elke keer als button wordt ingedrukt veranderd de string tot je de juiste stream die je wilt hebben in het scherm wordt weergegeven, ( bedenk dat TFT scherm telkens in deze file kijkt en gewoon weergeeeft wat er in die file staat ). Tweede button doet hetzelfde alleen bepaalt die de samplerate, telkens als op de knop wordt gedrukt komt er een andere samplerate te staan. Die file wordt ook gelezen door het programma wat de TFT scherm bedient en laat zien welke sample er gewenst wordt. Derde knop zorgt ervoor dat de gewenste stream wordt gestart en de DVB encoder wordt gestart op de Raspberry PI model B+ met IQ modulator. Laatste onafhankelijk programma kopieert de status van de encoder (als de encoder gestart is staat in de file welke sample rate, als hij gestopt is staat er ¨STOP¨. De status file is nodig om te bepalen of er gestart of gestopt moet worden. Als in de file de string ¨STOP¨ staat dan weet het button python script dat hij de boel moet opstarten, als er bv ¨2000Ks/S¨ in staat dan weet hij dat er een stream draait en zal dan de boel moeten stoppen.
Om ervoor te zorgen dat de Raspberry PI 2 commandoś mag uitvoeren op de Raspberry PI model B+ met IQ modulator wordt SSH zonder password gebruikt. In de python scripts wordt rekening gehouden met userID. De 3 porgrammaś worden opgestart via /etc/rc.local en klaar is kees. Voorbeeld zien hier te vinden en kunnen eenvoudig worden aangepast naar eigen smaak. Vrij eenvoudig om een nieuwe stream toe te voegen en zo door mideel va de buttons snel te kunnen selecteren en opstarten.
Binnenkant Cube
Schema VCO besturing ADF4351
Printontwerp VCO besturing ADF4351, inclusief 2 regelig display en rotary encode in Piggybag vorm.
Vooraanzicht VCO besturing, frequentie instelling VCO aan de zijkant van de DVB-S Cube
Script om status op te halen van de Raspberry PI model B+ met IQ modulator :
#/bin/sh while : do rcp pi@dvb:/home/pi/bla /home/pi/bla sleep 1 done
Python script voor TFT scherm welke aangesloten is op de Raspberry PI 2 van Admatec
#!/usr/bin/python # -*- coding: utf-8 -*- import os import sys import time import pygame import subprocess _image_library = {} def get_image(path): global _image_library image = _image_library.get(path) if image == None: canonicalized_path = path.replace('/', os.sep).replace('\\', os.sep) image = pygame.image.load(canonicalized_path) _image_library[path] = image return image pygame.init() window = pygame.display.set_mode((320,240)) font1 = pygame.font.SysFont("droidsans", 36) font2 = pygame.font.SysFont("droidsans", 28) font3 = pygame.font.SysFont("droidsans", 24) label3 = font3.render("PA0RJV", 1, (0,0,255)) label4 = font3.render("PE2JKO", 1, (0,0,255)) os.system("tft_init") os.system("tft_clear") os.system("tft_pwm 120") screen = pygame.display.set_mode((320, 240)) while True: try: window.fill(pygame.Color(0,0,0)) #lt = time.localtime() sep = "-" currentplay1 = subprocess.check_output(["cat", "/home/pi/bla"]) currentplay2 = subprocess.check_output(["cat", "/home/pi/rate"]) currentplay3 = subprocess.check_output(["cat", "/home/pi/stream"]) text1 = font1.render(currentplay1.strip(), 1, (255,255,0)) text2 = font1.render(currentplay2.strip(), 2, (255,0,0)) text3 = font1.render(currentplay3.strip(), 3, (0,255,255)) #text4 = font3.render(time.strftime("%H:%M:%S", lt), 1, (150,60,5)) rect1 = text1.get_rect() rect2 = text2.get_rect() rect3 = text3.get_rect() rect1.centerx = 160 rect1.centery = 210 rect2.centerx = 160 rect2.centery = 165 rect3.centerx = 160 rect3.centery = 120 screen.blit(get_image('/home/pi/540-1.png'), (20, 20)) pygame.display.flip() window.blit(text1, rect1) window.blit(text2, rect2) window.blit(text3, rect3) window.blit(label3, (200,20)) window.blit(label4, (200,50)) # window.blit(text4, (250,215)) pygame.image.save(window, "/ram/temp.bmp") os.system("tft_bmp /ram/temp.bmp") time.sleep(0.3) except KeyboardInterrupt: sys.exit()
Button script om de diverse streams op te starten en te selecteren :
#!/usr/bin/python import RPi.GPIO as GPIO import time import os import sys import subprocess GPIO.setmode(GPIO.BCM) GPIO.setup(2, GPIO.IN, pull_up_down=GPIO.PUD_UP) GPIO.setup(3, GPIO.IN, pull_up_down=GPIO.PUD_UP) GPIO.setup(4, GPIO.IN, pull_up_down=GPIO.PUD_UP) count = 0 count2 = 0 status = 0 os.setuid(1000) while True: input_state = GPIO.input(2) if input_state == False: #print('Button Pressed') count = count + 1 if ( count == 1 ): #print ("250") file = open("/home/pi/rate", "w") file.write("SET -> 250 kS/s \n") file.close() if ( count == 2 ): #print ("2000") file = open("/home/pi/rate", "w") file.write("SET -> 2000 kS/s \n") file.close() if (count == 3 ): #print ("2083") file = open("/home/pi/rate", "w") file.write("SET -> 2083 kS/s \n") file.close() count = 0 time.sleep(0.2) input_state = GPIO.input(3) if input_state == False: #print('Button Pressed') currentplay1 = subprocess.check_output(["cat", "/home/pi/bla"]) currentplay2 = subprocess.check_output(["cat", "/home/pi/rate"]) currentplay3 = subprocess.check_output(["cat", "/home/pi/stream"]) #print currentplay1 #print currentplay2 if (currentplay1 == "STOP\n"): if (currentplay2 == "SET -> 2000 kS/s \n" ): #print ("ok") os.setuid(1000) file = open("/home/pi/bla", "w") file.write("Starting... \n") file.close() # os.system("ssh pi@dvb ./2000") if (currentplay3 == "Camera \n" ): os.system("ssh pi@dvb ./2000") os.system("sudo /home/pi/2000 >/dev/null 2>&1 &") if (currentplay3 == "Camera MP2 \n" ): os.system("ssh pi@dvb ./2000") os.system("sudo /home/pi/2000-rpi-mp2-audio >/dev/null 2>&1 &") if (currentplay3 == "Camera noa \n" ): os.system("ssh pi@dvb ./2000") os.system("sudo /home/pi/2000-noaudio >/dev/null 2>&1 &") if (currentplay3 == "Testbeeld \n" ): os.system("ssh pi@dvb ./2000") os.system("sudo /home/pi/2000-testbeeld1252-control >/dev/null 2>&1 &") if (currentplay3 == "Testbeeld noa \n" ): os.system("ssh pi@dvb ./2000") os.system("sudo /home/pi/2000-testbeeld1252-control-noaudio >/dev/null 2>&1 &") if (currentplay3 == "Testbeeld2 noa \n" ): os.system("ssh pi@dvb ./2000") os.system("sudo /home/pi/2000-testbeeld1252-control-noaudio-2 >/dev/null 2>&1 &") if (currentplay3 == "Extern \n" ): os.system("ssh pi@dvb ./2000") if (currentplay3 == "Extern2 \n" ): os.system("ssh pi@dvb ./2000-mc2") time.sleep(0.1) if (currentplay2 == "SET -> 2083 kS/s \n" ): #print ("ok") file = open("/home/pi/bla", "w") file.write("Starting... \n") file.close() os.setuid(1000) #os.system("ssh pi@dvb ./2083") if (currentplay3 == "Camera \n" ): os.system("ssh pi@dvb ./2083") os.system("sudo /home/pi/2083-rpi-mp4-audio >/dev/null 2>&1 &") if (currentplay3 == "Camera MP2 \n" ): os.system("ssh pi@dvb ./2083") os.system("sudo /home/pi/2083-rpi-mp2-audio >/dev/null 2>&1 &") if (currentplay3 == "Testbeeld \n" ): os.system("ssh pi@dvb ./2083") os.system("sudo /home/pi/2083-testbeeld3-zdm >/dev/null 2>&1 &") if (currentplay3 == "Extern \n" ): os.system("ssh pi@dvb ./2083") time.sleep(0.1) if (currentplay2 == "SET -> 250 kS/s \n" ): #print ("ok") os.setuid(1000) file = open("/home/pi/bla", "w") file.write("Starting... \n") file.close() #os.system("ssh pi@dvb ./250") if (currentplay3 == "Camera \n" ): os.system("ssh pi@dvb ./250") os.system("sudo /home/pi/250-rpi-mp4-audio >/dev/null 2>&1 &") if (currentplay3 == "Testbeeld \n" ): os.system("ssh pi@dvb ./250") os.system("sudo /home/pi/250-rpi-mp4-audio >/dev/null 2>&1 &") if (currentplay3 == "Extern \n" ): os.system("ssh pi@dvb ./250-mc2") if (currentplay3 == "Extern2 \n" ): os.system("ssh pi@dvb ./250-mc3") time.sleep(0.1) else: os.setuid(1000) file = open("/home/pi/bla", "w") file.write("Stopping... \n") file.close() os.system("ssh pi@dvb ./stop") os.system("sudo /home/pi/stop >/dev/null 2>&1 &") time.sleep(0.2) input_state = GPIO.input(4) if input_state == False: count2 = count2 + 1 if ( count2 == 1 ): #print ("250") file = open("/home/pi/stream", "w") file.write("Testbeeld \n") file.close() if ( count2 == 2 ): #print ("2000") file = open("/home/pi/stream", "w") file.write("Camera \n") file.close() if (count2 == 3 ): #print ("2083") file = open("/home/pi/stream", "w") file.write("Extern \n") file.close() if (count2 == 4 ): #print ("2083") file = open("/home/pi/stream", "w") file.write("Extern2 \n") file.close() if (count2 == 5 ): #print ("2083") file = open("/home/pi/stream", "w") file.write("Testbeeld noa \n") file.close() if (count2 == 6 ): #print ("2083") file = open("/home/pi/stream", "w") file.write("Testbeeld2 noa \n") file.close() if (count2 == 7 ): #print ("2083") file = open("/home/pi/stream", "w") file.write("Camera noa \n") file.close() if (count2 == 8 ): #print ("2083") file = open("/home/pi/stream", "w") file.write("Camera MP2 \n") file.close() count2 = 0 time.sleep(0.2)
Eenvoudige Transport stream voorbeeld voor Raspberry PI 2 voor de RaspiCam, MPeg2 video en MP2 audio.
#!/bin/sh sudo rm /tmp/buffer2.ts sudo rm /tmp/testbeeld2.es sudo rm /tmp/testbeeld2.ts sudo killall avconv sudo killall tspcrstamp sudo killall tsudpsend # Make named pipes in /tmp folder for sending data between programs mkfifo /tmp/buffer2.ts mkfifo /tmp/testbeeld2.es mkfifo /tmp/testbeeld2.ts sleep 5 sudo nice -n -30 raspivid -s -n -w 352 -h 288 -b 1000000 -t 0 -pf high -fps 25 -g 12 -ih -o /tmp/video.es & # Encoding sudo nice -n -30 avconv -loglevel quiet -analyzeduration 0 -probesize 2048 -r 25 -fpsprobesize 0 -max_delay 40000 -i /tmp/video.es -f h264 -r 25 -minrate 1200k -maxrate 1200k -bufsize 120K -vcodec libx264 -f alsa -i plughw:1 -acodec mp2 -ac 1 -ab 32k -ar 48000 -f mp2 -f mpegts -mpegts_original_network_id 1 -mpegts_transport_stream_id 1 -mpegts_service_id 1 -streamid 0:101 -streamid 1:102 -muxrate 1843137 -y /tmp/testbeeld2.es & # #Change the pcr values to fix jitter after multiplexing (optional) /usr/local/bin/tspcrstamp /tmp/testbeeld2.es 1843137 > /tmp/buffer2.ts & /usr/local/bin/tsudpsend /tmp/buffer2.ts 239.0.0.1 1234 1843137 &
Het opstart script /etc/rc.local om de hele boel op te starten :
#!/bin/sh -e # # rc.local # # This script is executed at the end of each multiuser runlevel. # Make sure that the script will "exit 0" on success or any other # value on error. # # In order to enable or disable this script just change the execution # bits. # # By default this script does nothing. ~ # Print the IP address _IP=$(hostname -I) || true if [ "$_IP" ]; then printf "My IP address is %s\n" "$_IP" fi #/home/pi/start-local & ´2000 #/home/pi/2000 & sudo python /home/pi/disp8.py & sudo -H -u pi /home/pi/displ_background & sudo python /home/pi/button8.py & exit 0