Formal Language

2017-07-05

This is the description of a sensor board that measures the temperature and transmits it over 433.92MHz radio. It uses the protocol for the weather1 sensor in pimatic/rfcontroljs [1]. Four separate temperature sensors can be connected to the same board.

Components

Assembly

The Arduino is the backbone of the construction. Connect the battery connector to RAW and GND.

Analog 4 is used to monitor the battery health. The two 1 MOhm resistors form a voltage divider to get below 5V on the analog input. Connect one resistor between RAW and Analog 4. Connect the other resistor between Analog 4 and GND.

The KTY84 and the 1 kOhm resistor forms a voltage divider. KTY84 connects to GND and one of Analog 0, 1, 2 or 3. The resistor connects to the same Analog and VCC.

TX433N is powered by VCC and GND on the Arduino. Connect TX433N Data to Digital 2.

Connect the coil loaded antenna to Ant.

Configuration

The board is configured with messages sent on the serial port (115200 bps). The following values can be set.

where X selects one of the analog inputs 0, 1, 2 or 3. Each sensor transmit on separate weather1 channels 1, 2, 3 and 4. All sensors have the same id and measurement interval.

Example: To set the analog in 3 KTY84 zero degree resistance to 509 Ohm, send the following message, ending with newline.

31:509

The temperature measured by this KTY84 will transmit on channel 4.

Calibration

To calibrate the sensor, first measure the resistance of the 1 kOhm resistor and write the value to config X0. Then adjust config X1 until the measured temperature matches the value of a reference temperature. The sensor is disabled when X0 is zero.

Source Code

/* Copyright (C) 2017 Marcus Andersson

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see .*/

2017-06-26

This program comes with ABSOLUTELY NO WARRANTY.This is free software, and you are welcome to redistribute itunder certain conditions; GPLv3.

This is a proof of concept 433MHz ASK baseband decoder for messages sent byremote controls, weather stations, car keys and so on. It is written for Arduino,but the algorithm can run on anything that has GPIO IN with interrupt and amicrosecond time function.

You need a 433Mhz receiver. There are plenty of cheap receivers on the market [1].A good, compact antenna that I recommend is the DIY coil loaded antenna [2].

Connect the data out from the 433MHz receiver to digital 2 on Arduino. Uploadthis program using the Arduino IDE. Open a serial terminal set to 115200 bpsto start message reception. The output format is similar to homeduino [3],with a list of microsecond intervals followed by the message which consistsof indexes referencing the list.

Without an ongoing transmission, the receiver will pick up noise. We wantto ignore noise and only detect proper messages. A proper message consistsof a sequence of high/low signal pairs. The signals varies between 1 to Nperiods in length. A period is around 300 to 600 microseconds.

1_ _0_ | |_. = 11

1_ _0_ | |_._. = 12

1_ _._0_ | |_._._. = 23

...and so on.

A low signal that is longer than N periods is a sync. The high signal setsthe period time for the message. A sync is sent before and after a message.The sync signal can be shared by two adjacent messages, which means it marksboth the end of the first message and the start of the next.

1_ _0_ | |_._._._._._._._._._._._._._._._._._._._._._. = sync

When a sync signal is detected the message recording starts. As long as no signalhas a shorter duration than half a period, the reception continues until a new syncsignal is detected. There is a minimum length for a proper message and there isalso a minimum period time. This lowers the risk of interpreting noise as proper messages.

Incoming messages are written to a circular buffer by the interrupt routine. Ifthe reception buffer becomes full, the message being received is discarded. Whena complete message has been received the writer index is advanced to the positionafter the message and the main loop can start to consume the message using the readerindex. The first datum in the buffer is the period time in microseconds. The followingdata is the number of periods for all signals. The main loop transmits the message overthe serial port until (reader == writer) or until the number of periods of a datum islarger than N, which means that a new message starts.

2017-04-15

The power meter I have in my basement has a LED that blinks once every Wh. With a consuption of 3600W it will blink once every second. By logging the clock time at every blink it is possible to get a good overview of the consuption, both momentarily and over time.

The logger I have built is based on the Raspberry Pi Zero W. The LED sensor consists of a photo resistor and an transistor. It is connected to GPIO on the Raspberry Pi. An optional 16x2 LCD display is used to display the IP address of the logger and the current power consuption. A button is used to turn on the LCD backlight. Blink timestamps are logged to file and the data can be viewed in a Web GUI.

Mechanical Design

There is not much to say about the mechanical design. The LCD is attached to the RPi with a single M4 bolt and nuts. The logger and the sensor is attached with blu-tac to the power meter. The photo resistor have long legs that are bendable and can be used to finetune its position in front of the LED.

Electrical Design

The LED sensor is designed using a GL5528 photoresistor and a BC337 transistor to amplify the signal. The transistor collector and the photoresistor are powered with 3.3V from the RPi. The unpowered side of the photoresistor is connected to the transistor base. Without light on the photoresistor, the transistor will be closed and logical 0 will be measured by RPi GPIO 10 connected to the emitter. With light on the resistor, the transistor will open and logical 1 will be measured on RPi GPIO 10.

The 16x2 LCD is powered by 5V from the RPi and connected to GPIO in the following way.

2017-04-02

In the seventies, Seymour Papert invented LOGO as a teaching tool for
computer programming, encouraging exploration and interactivity. The
accompanying Turtle robot could draw sketches on paper, creating a
tangible thing from the programming effort. Now, the concept has been
recreated on a platform base on Raspberry Pi and Python.

The prototype Turtle

The prototype is more complicated than it has to be, mostly due to the fact that Raspberry Pi model A doesn't have built in Wifi and can't even supply a USB Wifi dongle with enough power on its own. Today the amazing Raspberry Pi Zero W can be used instead.

Development Environment

The Turtle is programmed using a Web IDE running on the robot itself.

The Integrated Development Enviroment

The IDE makes it possible to edit and run code on the Turtle. A history of executed programs are saved to make it easy to go back to an earlier version. It is also possible to save a program using a descriptive name. The console output of the running code is displayed in a separate text area to simplify debugging.

More than one person can program a single Turtle at the same time if they have one computer or tablet each and take turns running programs.

Mechanical Design

Wheels from inline skates are perfect for the Turtle. They are narrow with good friction which makes the robot turn in a tight and controlled way. To attach a wheel to a stepper motor shaft you need a mounting hub [6]. It is unlikely that you will find a hub that matches the holes on the wheels. I used a 1mm thick steel plate to adapt the mounting holes on the hub to the wheel.

Two stepper motors are used to drive the front wheels. The drawing
pen needs to be centered between the motors for the Turtle to be able to
turn on the spot without moving the pen. The pen should also be
possible to lift to be able to move the robot without drawing a line. I
found two copper plumbing parts in the local hardware store that fit
perfectly together without getting stuck or fall through. I attached the
pen to the narrow conical tube and placed six of the larger tubes
between the motors. I strapped it all together with cable ties and used
some blu-tac between the tubes to increase the friction.

On top of the engine pack I attached a 1mm thick steel plate to hold the electronics. Steel is probably not optimal for the Wifi signal and I would choose wood or plastic today.

As third supporting wheel I used a bearing ball but anything with low friction works fine.

The servo motor that is used to lift the pen is attached to a vertical steel plate that is glued to the base plate. Rubber bands push the pen down. The servo arm pulls a thread to lift the pen.

Electrical Design

The Turtle is powered by a rechargeable racing pack delivering 12V DC. To get the 5V DC that the Raspberry Pi requires, dual 5V/1A regulators [7] are used, one powering the Raspberry Pi and one powering the Wifi dongle through the USB hub.

The stepper motors are 200 steps/revolution, 12V DC. I use Easy Driver [8] to drive the stepper motors, one per motor. The STEP and DIR pins are connected to Raspberry Pi GPIO.

The servo that lifts the pen runs on 5V DC and is connected to the same converter that drives the Raspberry Pi. The signal wire is connected to Raspberry Pi GPIO.

2017-03-25

Makron (swedish for macaron) is the programming language used for text-based code generation in the Biotope application server. It is a kind of template or string processing language. It is typically used for server side generation of HTML code, but it is also suitable for any text based target languages like Graphviz, JSON, CSS and Javascript. The current implementation of the interpreter is tightly coupled with the relational model described in A Distributed and Relational Data Model.

Execution starts by invoking a well known template that is stored as a Code entity in the relational model and ends when the template is completely evaluated. A Makron template has access to the invocation URL and its parameters, can iterate over the result from a query to the relational model and can download content from the net and use all of these sources when composing its text-based result. Conditional execution is driven by regex matching, which also handles the limited parsing that is possible. A future goal is to include a proper parser generator. A Makron program is typically responsible for creating the response to GET requests to a Biotope servlet.

A Makron program cannot directly modify the relational data model. Instead, it is the JS/HTML application generated by the Makron evaluator that can modify the model through the Logger and Archiver servlets in Biotope.

High Level Language Overview

Everything is UTF-8 encoded text.

A string of text can be bound to a symbol. A symbol can either represent data or template code.

A string of text can be evaluated, which means that template invocations that are found in the text are substituted with the result of the recursive evaluation of the template (in a new local symbol scope). Templates are invoked using a language construct called a macaron, e.g. {template_name.arg1.arg2.arg3}. The rest of the text being evaluated is left unchanged.

Macaron start and end chars and argument delimiter chars are dynamically exchangeable to easily adapt to the properties of the target language.

Template arguments can either be evaluated in the invocation context or in the template context. The template itself explicitly performs eager, lazy or no evaluation of its arguments.

Hello, world!

A trivial program with no template invocations (macarons) will just output itself as the result.

Hello, world!

>>> Hello, world!

Before we get to more advanced evaluation rules we need some definitions.

Symbols

A symbol name can use the characters a-z, A-Z, 0-9, _ and -.

This_is_a_Symbol

Macarons

The default macaron start and end chars are '{' and '}'. It is a macaron that triggers template invocation and all characters in the macaron are part of the invocation.

{This is a macaron}

It is possible to change the macaron chars dynamically in the source by putting a macaron framed with new macaron chars directly inside a macaron. Valid macaron chars are '(', ')', '{', '}', '[', ']', and '<', '>'.

{(Parenthesis are now used as macaron chars within this macaron.)}

The change is tied to the lexical scope and does not affect templates that are invoked from within the macaron.

Escaped Chars

The escape char '\' can be used to prevent the normal interpretation of characters with special meaning, for example if you want to type a macaron char but don't want to start or end a macaron. It can also be used to insert newline '\n' and tab '\t'. A backslash is written '\\'.

Delimiter Chars

A delimiter char is a character not part of any of the other categories above. It is used to separate template name and the arguments in a macaron.

Now we have what we need to go on with template evaluation.

Template Evaluation

During evaluation, the template source code is read character by character and they are typically passed on unprocessed to the output stream. Escaped characters are passed on to the output stream without the escape char '\'.

Plain \{text\}

>>> Plain {text}

Template Invocation

When a macaron is encountered it is not passed on to the output
stream. Instead, template invocation is initiated. First, a template name
followed by a delimiter char is scanned for. The process is a form of
evaluation and other templates can be invoked during the scan. When a
delimiter char is found, evaluation stops and the rest of the unprocessed input
stream up to the end of the macaron is treated as the template
argument. The source code of the new template is loaded and evaluated in a
new scope with the variables self, '.', body, start and end bound to new values.

{template/with/{argument}/body}

Bindings in new evaluation scope:

self = template. = /body = with/{argument}/bodystart = {end = }

Function: = (let)

Makron is dynamically scoped with all the usual drawbacks, but don't
dismiss this language just yet. For small programs implementing view
generation, it is quite convenient to not have to specify all necessary
parameters in every template invocation. Symbols are semi-global, i.e.
global in its local execution branch. The code structure with one template
per file also doesn't make static scope very useful.

A symbol always refer to a stream of UTF-8 encoded text. Symbols can
be defined in the local scope using the built-in function let. It will evaluate both of its arguments before binding the first argument, the symbol name, to the second argument, the value.

{let.fn1.Hello, world!}

or

{=fn1=Hello, world!}

The content of the symbolfn1 can then be evaluated, i.e. a templateinvocation.

Makron says "{fn1}"

>>> Makron says "Hello, world!"

Template: ' (quote)

We will now define a second symbol containing code that calls fn1.

{=fn2={'{fn1}}}The argument to letis always evaluated, therefore we have to prevent the premature evaluation of {fn1} with the quote template. We could also escape the bracket or temporarily changed the macaron chars with the same effect.

{let.fn2.\{fn1\}}{let.fn2.{( {fn1})}}

The result when evaluatingfn2 is the same, as expected.

Makron still says "{fn2}"

>>> Makron still says "Hello, world!"

Function: $ (value)

If we instead want to get the content of the symbol fn2 without evaluating it, we can use the built-in function $.

{$$fn2}

>>> {fn1}

The reason for the double$$ is that $takes two arguments and we have given an empty first argument. It is very common that strings need to be escaped in different ways when inserting them in program code. Therefore the $ function takes a first argument that specify what kind of escaping that needs to be applied before output. A number of escape schemes are defined, e.g. qoute, squote, html, url.

{$url$fn2}

>>> %7Bfn1%7D

Function: [space] (identity)

As we saw above we can use the space function as a function that just evaluates and outputs its argument. This is for example useful when we want to change macaron chars but don't want to invoke a template as the first thing.

{( {fn1})}

>>> {fn1}

Functions: first and rest

If we break down the anatomy of a template invocation we can see that it consists of a template name followed by a delimiter char and the rest is the argument. Yes, always a single argument. The template
itself needs to break up the single argument into parts if it needs
multiple arguments. To be able to do this it can access the delimiter
char that was used in the invocation with the template '.', i.e. {.}. The unevaluated argument itself is bound to the variable body.

There are two helper functions first and rest that are useful when splitting up body. first returns the part before the first delimiter char and rest returns the part after the first delimiter char.

Function: @ (arg)

The function argworks like let with the difference that it evaluates the second argument twice, first in the local scope and the second time in the scope of the caller. This is the mechanism that turns the templateinto a function with eager evaluation of its arguments.

By convention, the last argument is assigned to what is left without looking for the delimiter char, i.e. no call to first. This means that the last part of body can include the delimiter char as data without the need to escape it.

Normally,
a function splits its argument at the delimiter chars and then
evaluates the parts separately. This allows variables containing
arbitrary strings to be passed as arguments. If the argument is first
evaluated as a whole and then split at the delimiter, the arbitrary
strings that are inserted into the argument may have introduced unwanted
delimiter or macaron chars that will ruin the intended argument
separation. first and rest are different though. They will first evaluate their argument and then look for the delimiter char.

Function: ~ (eval)

Sometimes it can be handy to be able to evaluate a string as a template without first bind it to a symbol. The function eval will evaluate its argument and then evaluate the resulting string once more.

Function: ^ (upeval)

The upeval function is a mix of eval and arg. It will evaluate its argument and then evaluate the resulting string in the scope where the current template was invoked.

Function: ? (query)

To get data from the relational model, the function query is used. The function evaluates the first argument and sends it as a sql query to the database. The second argument, when evaluated, is the code that will be evaluated for each row in the query result. The third argument, when evaluated, is the code that will be evaluated between each row. Brackets in the query will mark the symbol name to bind to each column in the result.

Function: % (regex)

Using regular expressions, it is possible to conditionally evaluate
Makron code. When the regex matches a string, one code path is evaluated.
If it doesn't match, another code path is evaluated. The whole input string must match, not just a part of it. The regex can also
be used as a simple parser as regex groups can be bound to variables in
Django style.

Pre-Defined Symbols

When the Makron evaluator is runningin a servlet context we very much like to get the URL and its parameters to be able to respond accordingly. The following symbols are pre-defined in such a context.

contexturl - Contains the URL to the servlet engine.rooturl- Contains the ULR to the servlet.url - Contains the part of the URL after rooturl. Always starts with '/'.p_xyz - Contains the value of the URL parameter xyz.

Symbols in the Relational Data Model

I mentioned earlier that the first function that was invoked would be retrieved from the relational data model. Symbols stored in the relational data model are available in the outermost scope. A symbol is represented by an entity in the relation code10c1. It is associated with a name through the chain code10c1-name11c11-text_value. The contents is stored in a web archive with an URL found through the chain code10c1-data11cn1-location02cn1-text_value.

Function: location

For symbols stored in the relational data model, it is possible to get the URL where the template data is stored.

Arithmetic Operations

Input Qualification

2017-01-01

Laser Trap: Dexterous Escape is a hobby project I have been working on for some time. In this post I will go though the things you will need to build your own laser course at home. The goal is to move as fast as possible through a room filled with laser beams without touching any of the beams.

The following tools are useful to have during the assembly of a laser trap. Soldering
iron, tin solder, flux, tweezers, nippers, toothpick (for the flux), microscope, Blu-Tack, permanent
marker and a FTDI USB TTL serial cable.

You need some experience at soldering to be able to put together a laser trap. Some of the components are quite small and can be difficult to handle for a beginner.

Main Board

The following parts are needed when assembling the main board for a laser trap.

Start by applying flux to the pads for R1, C1 and D1. This will make the components stick a little and you avoid having to chase the components around the board with the soldering iron. Place the components on the pads and solder them in place. Note that D1 have polarity and should be placed with the cathode pointing towards R1. The polarity is marked on the back with a T. The top side of the T is the cathode. (This is a bit strange as all guides on the net say the opposite, but the diode I am using, HSMH-C190, has its marking reversed.)

Put a small amount of Blu-Tack on the back of HM-10 and put it in place on the Main PCB and solder it to the seven pads. If you have Main PCB R1 (without revision marking) you only need to solder one of the four ground pads on the lower side. If you have a HM-10 module without USB as the one in the image, you don't even have pads for two of the ground connections.

Put U1 in position and solder the three legs and the heat sink in place.

Insert the leads from the 9V battery connector into the holes below U1 and solder them in place. Black is ground and should be soldered to the hole out in the corner of the PCB.

If you have Main PCB R1 you need to cut the copper trace that connects the two outer pads in the lower 3p connector. You should then connect the lower pad to one of the spare ground pads next to HM-10.

Put both 1x3p female connectors in position and solder them in place.

Mark the top side of the board as shown in the image.

Connect a 9V battery or another power source between 4.8V and 15V. The LED should start to blink. Attach a USB TTL serial cable to the serial terminals and exchange the following request response sequence at 9600-8N1.

AT+MODE1
OK+Set:1

AT+NAMELASERTRAP
OK+Set:LASERTRAP

The trap is now ready to connect to the Android application.

For lasers that draw more than 30mA the voltage regulator needs to be cooled more efficiently than what the PCB alone can manage. Attach the steel stripe with Blu-Tack on the opposite side of U1. This stripe is also useful for mounting the trap and sensor in the correct position to monitor the laser beam.

Sensor Board

The following parts are needed when assembling the sensor board for a laser trap.

Start by applying flux to the pads for R1. Place the component on the
pads and solder it in place.

Insert the two photo resistors at the top and the two photo resistors at the bottom into the mounting holes. Cut the leads and solder them in place.

Remove the pins from the two 1x1p male connector and put the remaining plastic tubes on the outer legs of the right and left photo resistors as support. Insert the three center row photo resistors into the mounting holes. Cut the leads and solder them in place.

Put the 1x3p male connector in position and solder it in place.

Red Laser

The following parts are needed when assembling the red laser for a laser trap.