Feb 7, 2021 - Learning Rust (and Maths)

Comments

Lerning Rust (and Maths)

Finally scheduled some time to learn Rust. I bought a book ages ago and also joined a course on Udemy, which was kind of alright, but didn’t really get me going. Then I found the Youtube channel of Ryan Levick, and it’s really great. I can highly recommend to fire up your IDE and code along watching his videos.

At the same time I’m trying to refresh my maths. Also ages ago I bought A Programmer’s Introduction to Mathematics. But as I rather used it for bedtime reading it didn’t really get me anywhere. So I thought I just take the ideas from there and try to implement them in Rust. This way I hopefully pick up both!

So far I’ve implemented the ‘Polynomial interpolation’ mentioned in the first few pages of the book, code on GitLab

Nov 17, 2020 - Python CLI script template

Comments

Python CLI script template

Usually my little Python scripts start with simply using sys.argv[] and print(). But after refactoring they always end up with a structure like this, using the argparse and logging libraries. It’s about time to put this in some kind of copy/pastable template:

import argparse
import logging


DESC = '''
This command line tool does something with a file.
'''

parser = argparse.ArgumentParser(description=DESC)
parser.add_argument("file", help="Some file to process")
parser.add_argument("output", nargs="?", help="Optional output file")
                             #nargs="+" for one or more positional arguments
parser.add_argument("-v", "--verbose", action="count", default=0,
                    help="Verbosity (-v, -vv, etc)")
parser.add_argument("-p", "--param", help="Some additional parameter")
parser.add_argument('--another', default="something", help="Optional parameter "
                                                           "with default value")
parser.add_argument('--flag', action="store_true", default=False,
                    help='Optional flag')

args = parser.parse_args()
loglevel = 30 - (args.verbose * 10)
logging.basicConfig(level=loglevel, format='%(levelname)s: %(message)s')


print(f"Do something with {args.file}")

if args.output:
  print(f"Write to {args.output}")

if args.param:
  print(f"With additional parameter {args.param}")

print(f"The other parameter is {args.another}")

if args.flag:
  print("The flag was set too.")

logging.debug("This is a debug message")
logging.info("This is an info message")
logging.warning("This is a warning message")
logging.error("This is an error message")

Paste this code in a file and have a play with it, especially using the different log levels by using -v, -vv etc. You’ll also notice that you automatically get a nice help (-h) message from argparse for free :-)

Oct 8, 2020 - Communication between Arduino Nano and Rasperry Pi via 2.4 GHz radio

Comments

Communication between Arduino Nano and Rasperry Pi via 2.4 GHz radio

Using the nRF24L01 chip and on both ends the RF24 library.

Check that the pins are correctly connected!

For this example on the Arduino CE -> D9 and CSN -> D10, hence RF24 is initialized with RF24 radio(10,9);. And on the Raspberry PI CSN -> 25 (it looks like CE doesn’t matter), hence radio is initialized with radio = RF24(25,0). The 0 comes from the SPI device name. Check with ls /dev | grep spi, e.g. spidev0.0 = 0 and spidev0.1 = 1, etc.

I’m still not quite sure, if the documentation is wrong about the pins or I just don’t get it.

Anyway with the above mentioned setup and the following code I got it finally working! The example is very simple and just send a timestamp from the Arduino to the Raspberry. But I hope you can use it for testing or as a template to build on.

Arduino

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"

RF24 radio(10,9);

const uint64_t rx_address = 0xF0F0F0F0E1LL;
const uint64_t tx_address = 0xF0F0F0F0D2LL;

void setup() {
  Serial.begin(115200);
  printf_begin();
  radio.begin();
  radio.enableDynamicPayloads();
  radio.setRetries(5, 15);
  radio.openWritingPipe(tx_address);
  radio.openReadingPipe(1, rx_address);
  radio.startListening();
  radio.printDetails();
  Serial.println(F("Setup done."));
}

void loop() {
  delay(5000);
  radio.stopListening();
  Serial.print(F("Now sending: "));
  unsigned long start_time = micros();
  Serial.print(start_time);
  Serial.print(F(" ... "));
  if (!radio.write( &start_time, sizeof(unsigned long) )){
    Serial.println(F("failed."));
  } else {
    Serial.println(F("ok."));
  }
}

Raspberry Pi

from __future__ import print_function
import time
from RF24 import *
import RPi.GPIO as GPIO

tx_address = 0xF0F0F0F0E1
rx_address = 0xF0F0F0F0D2

radio = RF24(25,0);
radio.begin()
radio.enableDynamicPayloads()
radio.setRetries(5, 15)
radio.openWritingPipe(tx_address)
radio.openReadingPipe(1, rx_address)
radio.startListening()
radio.printDetails()

print("Listening...")
while True:
	radio.startListening()
	if radio.available():
		receive_payload = radio.read(4)
		print("{}".format(int.from_bytes(receive_payload, 
			byteorder='little', signed=False)))
		time.sleep(0.1)