There was need for an antenna for our SatNogs (Satellite Ground Station Network). As serious hackers there was no other option than to build one of our own. After several more or less unsuccessful experiments with several antenna types we decided to build a Lindenblad antenna for the 2 meters (144 Mhz frequency) range. We are Ronny (DL7ROX) and myself (DM1AS). There are several papers and discussions available on how to build such an antenna, most of them vom Amsat and US in general.
The cross connection in between the 4 dipoles is the same aluminium tube with a length of 584 mm.
The wires
As we have 4 dipoles of 50 Ohm impedance in parallel and the wire typically as 50 Ohm we need to match it. The solution in the paper is to use an 75 Ohm TV wire with a defined range so it will match the 200 Ohm to the 50 Ohm of the wire impedance.
impedance matching wire
A
584 mm
B
5 mm
C
8 mm
Put it all together
Each dipol will be connected to one impedance matching wire and all 4 wires to the antenna wire. Don’t forget a cable ferrite on each of the impedance matching wires very close to the dipol side. The 4 dipoles will then be connected opposite to each other and each dipole rotated by 30 degrees clockwise to the horizon.
Measure the SWR
SWR-Lindenblad
We measured the dimensions with an AA-1400 and where very proud to get such a great result of 1 at the center frequency.
Sometime you want to print you logo or some text on your 3D object with different filament but you only have a single head printer and don’t want to spend all the time sitting next to your printer to wait for the right moment to manually pause the print and change the filament. Like the Motionlab logo on the picture. For sure you could print it separately and glue it on the main printed part but specially with text it’s a lot of tiny parts to take care of and align. If you are lucky and have a dual print head it’s not a problem but there is also a way to do it very simple with a singe print head by editing the G-Code file and add G-Codes by hand.
The solution
There is a G-Code named G199. Regarding to Craftware the purpose of the code is “G199 pauses the print immediately, and moves the head to X0, Y100. (this is the command the LCD screen uses)”. So by adding this code by hand the printer stops printing and moved the head to the side. After changing the filament (and also extrude some more by hand to make sure the printer is ready) you can press “continue” on the printer display.
Prepare the SVG file
If your logo is already in SVG you are lucky. Otherwise try to convert it to SVG and make sure it’s in connected objects. If you need some geeky stuff I can recommend Geeksvgs.
Use Fusion360 to create the STL logo file
Fusion360 insert SVG
In Fusion360 use Insert -> Insert SVG -> Select SVG File to open the SVG file on a Sketch. Resize and stretch it as you like or the dimensions dictate.
Next step is to extrude the logo to a 3D object. This can be done simply by “Stop Sketching” and then press “e” for extrude. Select everything by drawing a frame with your mouse. Unfortunately fusion has no idea witch part of the logo should be extruded and witch not. Press and hold CTRL and deselect the inner parts of the logo. For example the circle in the “o”. I recommend extracting 10 mm even if you only want to rise the logo by 4 mm.
As the single objects are not connected fusion creates several bodies instead of one.
Save single STL
A single STL file with all Bodies included at the right position can be exported by pressing the Component name and press the right mouse button.
Combine both STL in your slicer
Now as we have two STL files we can load them both at the same time in our slicer (no matter witch one). Position your logo at the right place, scale it and change the z access offset accordingly to your needs.
Combine STLs
As we extruded the logo 10 mm there is enough space to play around. Make sure at least one mm is submerged in your main body.
Manually edit the gcode to add the pause sequence
Find the right Layer
Now we need to find the right place in the G-Code itself. Our slicer can help us with the preview mode. The best layer is the second one after the main body is done and the logo starts to be printed.
Mark down this layer and open the G-Code in your favorite text editor. All slicers I used always make nice comments in the code to find the light position. Search for “layer nnn” and add the “G199” statement.
Just print the G-Code as you always do. As soon as the printer reads and process the G199 comment it stops printing and moves the head to the left side. All heating settings remain the same and you can easily replace your filament and press “Continue” or “GO” on your printers screen. Happy printing.
Adding the 4 channel relay board ks0212 to the MQTT universe
We just hacked a trotec dehumidifier for HerwigsObservatory. The idea was to additionally activate the dehumidifier when the difference between outside and inside humidity is above 10%. Normally there is a fan taking care of it but sometimes the differents gets to high. As there is already a raspberry pi running in the observatory for the weatherstation and the flightradar24 installation we just added the 4 channel relay board ks0212 from keyestudio. Not touching the 220V part we directly used the relay to “press” the TTL switch on the board for 0.5 seconds to turn on and off the dehumidifier. Here are the code snipped we used for this. The control is completely handled via MQTT.
For the sake of simplicity we used python and the GPIO library wiringpi. Therefore we first install the python development parts and them the python libraries for wiringpi and MQTT. As this is a dedicated hardware installation we don’t use virtualenv and directly install the library as root system wide.
The python program
import time
import wiringpi
import paho.mqtt.client as mqtt
def setup():
wiringpi.wiringPiSetup()
wiringpi.pinMode(3, 1)
wiringpi.pinMode(7, 1)
wiringpi.pinMode(22, 1)
wiringpi.pinMode(25, 1)
def short(pin):
switch_on(pin)
time.sleep(0.5)
switch_off(pin)
def switch_on(pin):
wiringpi.digitalWrite(pin, 1)
def switch_off(pin):
wiringpi.digitalWrite(pin, 0)
def on_connect(self, client, userdata, rc):
mqclient.subscribe("sternwarte/relay/#")
def on_message(client, userdata, msg):
m = msg.topic.split("/")
pin = 0
if m[-1] == "j3":
pin = 3
if m[-1] == "j2":
pin = 7
if m[-1] == "j4":
pin = 22
if m[-1] == "j5":
pin = 25
if pin != 0:
if msg.payload == "on":
switch_on(pin)
if msg.payload == "off":
switch_off(pin)
if msg.payload == "press":
short(pin)
if __name__ == "__main__":
setup()
mqclient = mqtt.Client(clean_session=True)
mqclient.connect("192.168.2.5", 1883, 60)
mqclient.on_connect = on_connect
mqclient.on_message = on_message
mqclient.loop_forever()
Again, a very simple python script, basically attaching to a (you need to change the code, there is no config) mqtt server and subscribes itself to a certain topic. Then it waits for messages and cuts off the last part of the topic to identify the relay. The naming convention is based on the relay name printed on the ks0212 pcb. As payload you can send “on“, “off” and “press“. “press” switches the relay on for half a second in order to simulate a button press as we need it for our dehumidifier.
Adding a systemd service
In order to keep the wantabe daemon up and running and also start it automatically at system start we add this service configuration file in “/lib/systemd/system/relayboard.service“:
If you want to do some hacking with the ks0212 relay board on your own here is the pin mapping table. I used the very cool side https://pinout.xyz/pinout/wiringpi for getting the numbers:
Thanks to the esp8266 project on github there is a very convenient way how an ESP can be updated over the air. There are three different ways available.
The first one is via the arduino IDE itself where the esp opens a port and is available for firmware upload just like with a serial connection. Very convenient if you are in the same network.
The second one is via http upload. So the esp provides a web server to upload the bin file. In this case there is no need to be in the same network but it is still a push and for each installed esp individual necessary.
The third and most convenient way for a bigger installation base or in case the devices are behind a firewall (as they always should be) and no remote access is possible. In this case the device can download the firmware itself via http(s) download from a web server somewhere in the internet.
For a complete dev-ops pipeline from pushing to a repository to flashing a device the third scenario it the easiest one. So we need a place to store the binary files. For convenience I use amazon s3 to host my binary files as travis easily supports s3 upload. But it can be every internet platform where files can be stored and downloaded via http(s). The necessary code on arduino side looks like this:
#define BUILD_VERSION REPLACE_WITH_CURRENT_VERSION
#define ULR_FIRMWARE_BIN "http://s3.amazonaws.com/feelflight/firmware/blanked.bin"
#define URL_FIRMWARE_VERSION "http://s3.amazonaws.com/feelflight/firmware/blanked.version"
void checkForNewFirmware(void){
HTTPClient http;
http.begin(URL_FIRMWARE_VERSION);
int httpCode = http.GET();
if(httpCode == HTTP_CODE_OK) {
String payload = http.getString();
int newVersion = payload.toInt();
if (BUILD_VERSION < newVersion){
Serial.println("I need to update");
t_httpUpdate_return ret = ESPhttpUpdate.update(ULR_FIRMWARE_BIN);
if (ret == HTTP_UPDATE_FAILED){
Serial.printf("HTTP_UPDATE_FAILD Error (%d): %s\n", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str());
}
}
}
}
This arduino function can be called from time to time (at startup or on constant running systems every now and then) to check for a new firmware version and in case there is a new version available automatic flash it and restart.
Line 1 is a #define with a placeholder for the current version of the installed firmware. This placeholder is replaced in the build pipeline at travis with an increasing number. So the compiled code has something like 23 or 42 instead of REPLACE_WITH_CURRENT_VERSION.
Line 2 is the URL for a latest version of a firmware.
Line 3 is the URL to a file with only one line with the latest build number in it.
Line 7-9 loads the version file from s3.
Line 12-13 converts the file into a number which can be compared with the define from line 1.
Line 17 is the firmware update itself. A detailed description of the ESPhttpUpdate class can be found here.
There are two ways to check if there is a new version available and only flash if there is something new. The one we use here is to have an own mechanism for it. I do it because on s3 I can only host static files and therefore I place the latest build number in a static file next to the firmware itself. The other way is build in into ESPhttpUpdate. The update function can be called with a build number which will be compared on the server and the return code will reflect if there is a new version or not. In this case we would need a script on the server to check for it.
Get an increasing build version number
With a little bash script we could load the last build number from s3 and then increase it in order to have the current number for our build.
#!/usr/bin/env bash
let oldversion=`curl http://s3.amazonaws.com/feelflight/firmware/blanked.version`
let newversion=oldversion+1
echo "============="
echo "New Version:"
echo $newversion
echo "============="
sed -i "s/REPLACE_WITH_CURRENT_VERSION/$newversion/g" src/main.cpp
echo $newversion > upload/blanked.version
This script loads the version file (line 3), increases the number (line 4) and patches our source code file (line 11) with this number instead of REPLACE_WITH_CURRENT_VERSION. After running this script the current source code contains the latest number and also the upload folder for s3 has a new file with the newest number in order to inform the polling ESPs.
Travis config file
Travis-ci is incredible easy to use and very reliable for continuous integration. In combination with platformio it is very easy to compile arduino code for several types of hardware. Simply configure the hardware in the platformio.ini file:
Line 1: Platformio is based on python so the build environment (although the code is c++) is python for maintaining platformio.
Line 3: Right now platformio is only available for python 2.7 so this line gets the latest stable version of python 2.7.
Line 5-7: Gets the latest cache files from the last build in order to save compile time and reduce the costs for travis. As this service is for free for open source projects it is always nice to save some money for the cool guys.
Line 10: Installs the latest version of platformio itself.
Line 13: Creates the upload directory which we will upload to s3 later on.
Line 14: Calls the build number increase and patch script.
Line 15-16: Patches the wireless lan config in case it is not handled inside the arduino code itself.
Line 17: Calls platformio to download all libraries and compile the arduino code itself.
Line 18: Platformio generates a lot of files for the linker and several other files. We only need the bin file later on, so we copy it here to the upload folder.
Line 20: Travis has a build in functionality to upload files after compilation. This is the part where we upload the files to s3.
Line 22: Defines the s3 bucket to upload the files.
Line 23-26: Provides the encrypted s3 credentials. See travis documentation on how to create these lines.
Line 29: Defines the local folder to be uploaded. Otherwise travis will upload everything from the current run.
Line 30: Defines the s3 folder in the bucket where the files will be stored.
With this files in place travis monitors your github repository and creates / uploads new firmware versions each time you push changes to your repository. The arduino code checks for new versions and patches itselfs as soon as there is a new version available. A complete project can be found here in my github repository.
Last weekend the c-base and friends team had a great time doing some hacking with Narrow Band IoT (NB-IoT) from Deutsche Telekom at the nbiot-hackathon at hub:raum. We could put our hands on the BC95 chip, a dev board and access to the Telekom test network. Beside hacking we had a great time with funny hats and our obligatory overalls.
The BC95 Board
The board we could use was the BC95-B8 board which we mounted on a development board with a support controller and serial converter. Beside the board setup we also soldered a PCB with some sensors and a Teensy board to control the BC95 and the sensors.
Wiring
Pin-Connection
The dev board itself has a RS232 converter to give access via “normal” RS232 connectors. This is convenient for older laptops or desktops but luckily they also give you access via 3.3V pegel to the same UART interface. The pins are pre soldered on a 10 pin header so it’s easy to connect this to arduino or Raspberry PI via the serial connection. As you can see in the picture it is pin 1,2 and 6. No level converter necessary.
AT- Command Set
AT // First handshake will be used for out speed detection may be result in ERROR
AT // Repeat sending "AT" until you receive an "OK"
AT+NRB // Reboot the device in order to have a clean start
//wait for the reboot
AT+NBAND=8 // Set the communication band in this case 900Mhz
AT+CGDCONT=1,"IP","NBIOT.Telekom" // Sets the APN (Access Point Name)
AT+CEREG=2 // Connect to the IoT Core
AT+CFUN=1 // Power on the module
AT+COPS=1,2,"12345" // Force the module to connect to the network
// wait for the network connection (some seconds)
AT+NPING=8.8.8.8 // Ping a server to check if it works
AT+NSOCR=DGRAM,17,16666 // Open a UDP socket
AT+NSOST=0,ansi.23-5.eu,16666,4,414E5349 // Send out the data
Line 1,2
The serial protocol can be any speed at 8N1, the board auto detects the speed at first communication, therefore you need to send the AT command several times (normally 2) to set the speed. Normally the first AT command is answered with ERROR and the second one with AT. Make sure you get an OK before you continue.
Line 3
In order to get a clean setup we first reboot the board with “NRB”. It takes some seconds and it will come back with OK.
Line 7
Depending on your network you need to set the band with “NBAND”. The Telekom test network is on 900 MHz so we go with 8. Other bands are 5 (850 Mhz) and 20 (800 MHz).
Line 8
Depending on your setup and provider you need to set the APN with the CGDCONT command.
Line 9
Connect to the IoT Core
Line 10
Power on the module
Line 11
Connect to the network. This can take several seconds even a minute. You can always check the connection with at+cgatt?” and check for “+CGATT:1”. You can double check the existing connection by asking for the IP address which is assigned to you by sending “at+cgpaddr=1” to get for example “+CGPADDR:1,10.100.0.16”.
Line 15
Ping a server to test everything is fine. (In this case the google DNS server)
Line 16
Open an UDP socket to receive answers. In our case the DGRAM and 17 are mandatory but the port you are using (in our case 16666) is up to you.
Line 17
Send your UDP data package. First parameter is the out port (0). The second one is the address you want to send the data to (ip or name). Third one is the receivers port (16666). Fours is the amount of data you want to send (keep it below 100 bytes) and the last one is your data in hex notification. I recommend asciitohex.com to convert a string you want to send.
This arduino code is really a fast and ugly hack for the hackathon in order to send out the data. It does not listen for the AT returns or anything else. So this is only an example on how NOT to do coding but it worked for the hackathon.