SSTV
- Embedded device + screen, mounted on a wooden plate
- ethernet cable (Sarjah)
- mini jack, 3.5mm to rca mono (active speaker)
- ADAM A3X: 1 active speaker 50Watt (Sarjah) https://www.adam-audio.com/en/ax-series/a3x/
- multiplug for mim 3 electricity plugs (110/220V, AC)
-----------------------------------------------------------------------------------------------
TX /RX
raspberry pi : + SD cARD
ip:
UPLOAD
http://188.210.92.35:8080
PYSSTV: install: https://pypi.python.org/pypi/PySSTV
prepare images
format: png !
best size: 320*240 Image must be at least 320 x 256 pixels for mode MartinM1
https://en.wikipedia.org/wiki/Slow-scan_television
Martin M1 240 lines
INSTALL
regenerating host keys
( https://www.cyberciti.biz/faq/howto-regenerate-openssh-host-keys/ )
#rm -v /etc/ssh/ssh_host_*
#dpkg-reconfigure openssh-server
pysstv (img > wav)
#sudo apt-get update
#sudo apt-get install python-imaging
#sudo apt-get install python-pip
#sudo apt-get install python-pil
#sudo pip install pysstv
slowrx compiling
#sudo apt-get install libgtk-3-0 libgtk-3-dev
#sudo apt-get install libasound2-dev
#sudo apt-get install libfftw3-dev
#git clone https://github.com/windytan/slowrx.git
#make
#sudo apt-get install xserver-xorg-video-fbturbo
#sudo apt-get install xinit
need to rusun xserver as root user... (virtual console tty0 mess otherwise...)
AUTO START
--------------------------------------------------------------------
blank screen
@xset s noblank
@xset s off
@xset -dpms
adapt config
autologin jessie
http://www.linuxserve.com/2015/06/how-to-enable-automatic-login-on-debian.html
prevent screen faalot
Also edit /etc/kbd/config and make sure these values are set as follows (however I believe this is only for when the lightweight desktop (LXDE) is not running (i.e. the pi is still in text / terminal mode):
BLANK_TIME=0
BLANK_DPMS=off
POWERDOWN_TIME=0
--------------------------------------------------------------------
NEW VERSION
--------------------------------
install lightdm
raspi-config -> boot into xwindow & autologin (boot options)
snd-aloop
(plugin loopback - virtual audiocard to pipe the playes wav into slow rx))
gst-launch-1.0 -v filesrc location="./out.wav" ! decodebin ! audio/x-raw ! tee name=t t. ! audio/x-raw ! queue ! alsasink device=plughw:1,1,0 t. ! audio/x-raw ! queue ! alsasink device=plughw:0,0
COMPILE SLOWRX
slowrx
NECESARY LIBRARIES
libgtk-3-dev libfftw3-dev libasound2-dev
INSTALL PYSSTV + IMAGEMAGICK (convert)
pysstv
sudo apt-get install python-imaging
sudo apt-get install imagemagick
python -m pysstv ./images/b.png out.wav
INSTALL GSTREAMER - for 2-way audio playback (soundloopback to slow rx + audio output to speakers
sudo apt-get install gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-ugly gstreamer1.0-plugins-bad gstreamer1.0-nice gstreamer1.0-libav gstreamer1.0-alsa
INTERFACE
(remove mouse cursor-
(window position commando)
???
unclutter
xdotool
export DISPLAY=:0.0
xdotool search --onlyvisible --class 'slowrx' windowmove %@ -200 -150
----
moet image_rx nog aanpassen (slowrx.ui)
--- -- - - - - ---
# loopback soundcard
pi@seedmast:~ $ cat /etc/modules
# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.
snd-aloop
----- -- - - - - - raspiconfig
# pi autologin
pi@seedmast:~ $ cat /etc/systemd/system/getty@tty1.service.d/autologin.conf
[Service]
ExecStart=
ExecStart=-/sbin/agetty --autologin pi --noclear %I $TERM
----- -- - - - - -
# auto login X environment
pi@seedmast:~ $ vi /etc/lightdm/lightdm.conf
autologin-user=pi
autologin-user-timeout=0
--- -- - - - - ---
INSTALL xdotool
#xsession - load session on startup
pi@seedmast:~ $ cat .xsession
@xset s noblank
@xset s off
@xset -dpms
cd /home/pi/slowrx/
/home/pi/slowrx/slowrx &
sleep 10
xdotool search --onlyvisible --class 'slowrx' windowmove %@ -200 -193
unclutter
(installeren unclutter - x -...?)
- - -------- - -
# hack User Interface of slowrx
diff --git a/common.c b/common.c
index be4a97b..bfe4a6b 100644
--- a/common.c
+++ b/common.c
@@ -175,8 +175,8 @@ void evt_clickimg(GtkWidget *widget, GdkEventButton* event, GdkWindowEdge edge)
if (event->type == GDK_BUTTON_PRESS && event->button == 1 && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(gui.tog_setedge))) {
- x = event->x * (ModeSpec[CurrentPic.Mode].ImgWidth / 500.0);
- y = event->y * (ModeSpec[CurrentPic.Mode].ImgWidth / 500.0) / ModeSpec[CurrentPic.Mode].LineHeight;
+ x = event->x * (ModeSpec[CurrentPic.Mode].ImgWidth / 640.0);
+ y = event->y * (ModeSpec[CurrentPic.Mode].ImgWidth / 640.0) / ModeSpec[CurrentPic.Mode].LineHeight;
if (secondpress) {
secondpress=FALSE;
diff --git a/gui.c b/gui.c
index 63a0d17..4a95db0 100644
--- a/gui.c
+++ b/gui.c
@@ -62,7 +62,7 @@ void createGUI() {
pixbuf_rx = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, 320, 256);
gdk_pixbuf_fill(pixbuf_rx, 0x000000ff);
- pixbuf_disp = gdk_pixbuf_scale_simple (pixbuf_rx, 500, 400, GDK_INTERP_BILINEAR);
+ pixbuf_disp = gdk_pixbuf_scale_simple (pixbuf_rx, 640, 480, GDK_INTERP_BILINEAR);
gtk_image_set_from_pixbuf(GTK_IMAGE(gui.image_rx), pixbuf_disp);
pixbuf_PWR = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, 100, 30);
diff --git a/pcm.c b/pcm.c
index db97df1..47a9a45 100644
--- a/pcm.c
+++ b/pcm.c
@@ -139,9 +139,9 @@ int initPcmDevice(char *wanteddevname) {
}
if (strcmp(wanteddevname,"default") == 0) {
- sprintf(pcm_name,"default");
+ sprintf(pcm_name,"hw:0,1,0");
} else {
- sprintf(pcm_name,"hw:%d",card);
+ sprintf(pcm_name,"hw:0,1,0",card);
}
if (snd_pcm_open(&pcm.handle, pcm_name, SND_PCM_STREAM_CAPTURE, 0) < 0) {
diff --git a/slowrx.ui b/slowrx.ui
index 85e5d62..9d7d21b 100644
--- a/slowrx.ui
+++ b/slowrx.ui
@@ -160,8 +160,8 @@
<property name="visible_window">False</property>
<child>
<object class="GtkImage" id="image_rx">
- <property name="width_request">500</property>
- <property name="height_request">375</property>
+ <property name="width_request">640</property>
+ <property name="height_request">480</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-missing-image</property>
diff --git a/video.c b/video.c
index e479b2d..7b883a8 100644
--- a/video.c
+++ b/video.c
@@ -166,8 +166,8 @@ gboolean GetVideo(guchar Mode, double Rate, int Skip, gboolean Redraw) {
pixels = gdk_pixbuf_get_pixels(pixbuf_rx);
g_object_unref(pixbuf_disp);
- pixbuf_disp = gdk_pixbuf_scale_simple(pixbuf_rx, 500,
- 500.0/ModeSpec[Mode].ImgWidth * ModeSpec[Mode].NumLines * ModeSpec[Mode].LineHeight, GDK_INTERP_BILINEAR);
+ pixbuf_disp = gdk_pixbuf_scale_simple(pixbuf_rx, 640,
+ 640.0/ModeSpec[Mode].ImgWidth * ModeSpec[Mode].NumLines * ModeSpec[Mode].LineHeight, GDK_INTERP_BILINEAR);
gdk_threads_enter();
gtk_image_set_from_pixbuf(GTK_IMAGE(gui.image_rx), pixbuf_disp);
@@ -380,8 +380,8 @@ gboolean GetVideo(guchar Mode, double Rate, int Skip, gboolean Redraw) {
if (!Redraw || y % 5 == 0 || PixelGrid[PixelIdx].Last) {
// Scale and update image
g_object_unref(pixbuf_disp);
- pixbuf_disp = gdk_pixbuf_scale_simple(pixbuf_rx, 500,
- 500.0/ModeSpec[Mode].ImgWidth * ModeSpec[Mode].NumLines * ModeSpec[Mode].LineHeight, GDK_INTERP_BILINEAR);
+ pixbuf_disp = gdk_pixbuf_scale_simple(pixbuf_rx, 640,
+ 640.0/ModeSpec[Mode].ImgWidth * ModeSpec[Mode].NumLines * ModeSpec[Mode].LineHeight, GDK_INTERP_BILINEAR);
gdk_threads_enter();
gtk_image_set_from_pixbuf(GTK_IMAGE(gui.image_rx), pixbuf_disp);
---- -- -- -- - -
TRY: BATCH CONVERTING IMAGES
pi@seedmast:~ $ cat monitor_upload.sh
#!/bin/bash
set -x
inotifywait --monitor --exclude '/\.' -e close_write,moved_to --format '%f' /home/pi/upload/
|
while read -r file
do
file_noext=$(echo "$file" | cut -f 1 -d '.')
cp "/home/pi/upload/${file}" "/home/pi/convert_upload/${file_noext}.png"
mogrify "/home/pi/convert_upload/${file_noext}.png[!320x256<]"
mogrify "/home/pi/convert_upload/${file_noext}.png[!320x256>]"
python -m pysstv "/home/pi/convert_upload/${file_noext}.png" "/home/pi/convert_upload/${file_
noext}.wav"
done
KEY exchange ( copy pub key to server for authenticated exchange > authorized keys)
ssh-copy-id root@188.210.92.35 -p 8022
e.g copy syncing
scp -r /home/ooooo/Documents/PERFORM/PERFORM-flatbread/SSTV/horizon/transmit/ pi@10.94.185.132:.
rsync --progress -ra /home/ooooo/Documents/PERFORM/PERFORM-flatbread/SSTV/horizon/transmit/ pi@10.94.185.132:/home/pi/transmit
CRONTAB
# TEST RSYNC
rsync -ave "ssh -p 8022" root@188.210.92.35:/var/www/uploads/ /home/pi/upload
# TEST RSYNC keep server alive
/usr/bin/rsync -ave "ssh -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes -o StrictHostKeyChecking=no -i /home/pi/.ssh/id_rsa -p 8022" root@188.210.92.35:/var/www/uploads/ /home/pi/upload/ --progress
crontab -e
uploading images --
imagemagick /resize images
- via WirelessBelgie server -- rsync + processing (imagick / pysstv)
*ip adres
*ssh -p8022 root@188.210.92.35
*5.196.109.240/
*
rsync : rsync --progress -ra root@188.210.92.35:/shares
rsync -ave --progress ssh root@188.210.92.35:/var/www/uploads /home/pi/upload
- reverse ssh can be nice..
ssh --
reverse ssh
server makest connecion with client
-- reverse ssh --
---- pi ---
ssh-keygen -f ~/.ssh/id-rsa
root@rx:/etc/systemd/system# cat /etc/systemd/system/phone-home.service
cat /etc/systemd/system/phone-home.service
[Unit]
Description=Phone Home Reverse SSH Service
After=network.target
[Service]
Type=simple
User=pi
ExecStart=/usr/bin/ssh -NTC -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes -o StrictHostKeyChecking=no -i /home/pi/.ssh/id_rsa -R 12345:localhost:22 root@188.210.92.35 -p 8022
# Restart every >2 seconds to avoid StartLimitInterval failure
RestartSec=5
Restart=always
[Install]
WantedBy=multi-user.target
monitor_upload.service
*[Unit]
*Description=Notifywait new uploads
*After=network.target
*
*[Service]
Type=simple
User=pi
ExecStart=/home/pi/monitor_upload.sh
*Restart=always
*RestartSec=5
*
*[Install]
*WantedBy=multi-user.target
sudo systemctl enable monitor_upload
---- WA server ----
ssh pi@localhost -p 12345
... pasword of rpi rx box
file monitoring
https://anarc.at/blog/2019-11-20-file-monitoring-tools/#inotify-hookable