Close

Building and Coding the Initial Prototype

A project log for Tangible programming

An Arduino-based tangible programming effort

amosAmos 03/02/2019 at 12:190 Comments

I mentioned earlier that this project started as a university assignment. For the assignment, I chose to implement a small subset of the language I had defined, namely: Variables; Output; and Loop/EndLoop. To simplify detecting the end of a program I also included an END_PROGRAM block.

For the variables, I used the four brightly coloured breadboards in the mini-breadboard pack I had. That gave me an easy way to refer to the variables - use the colour of their breadboard - giving me four variables, Blue, Red, Green and Yellow. The four variables defaulted to a value of 0 and could be assigned the value of another variable, a two-digit integer, or a simple expression comprising two operands and an operator.

Output was quite simple - it would output the value of a specified variable.

Loops could be programmed to repeat a set number of times.

For both Output and Loop, their input parameters were dongles I created to represent each of the four variables. These dongles could be plugged into the breadboard of the Output/Loop module and read via the relevant GPIO pins. As a shortcut, I allowed variables to assigned using the same system, avoiding the need for too many PCF8574-powered value blocks and expression blocks.

While it added complexity to the Arduino sketch, I decided to use a single codebase for all the programming blocks. Therefore, when a block is first powered up, the code checks for some jumpers on three GPIO pins to determine the block's type which is stored in a block_id variable. Then it checked to see if there were any I2C devices at addresses 0x20 and 0x21 - the addresses of the PCF8574 ICs. If only one device was found, that must be a single value module, if both addresses were found we have a full expression module. The block then enters its loop() loop, waiting for any incoming messages on both the hardware serial port and the software AltSoftSerial port.

The master controller (I used an Arduino Uno with a small OLED display for this) would send a broadcast message (WHO_IS_THERE) on the serial port asking any attached modules to identify themselves and then enters its own loop() to wait for any replies.

When a block receives a WHO_IS_THERE request, it will respond depending on its internal block_id:

After sending the WHO_IS_THERE command, the Master Controller waits for responses until it receives an EndProgram, storing the block_ids and their parameters in an array. Once the EndProgram has been detected, the Master Controller switches to execute program mode.

To execute the program, the Master Controller steps through the program array, interpreting each command as it goes, maintaining an internal representation fo the four variables. To indicate the progress of the execution, the Master Controller will instruct the currently executing block to display its green LED. All Output commands cause the respective variable's name and value to be displayed to the attached OLED display. Execution continues until the EndProgram block is reached, or an error is encountered. If an error is detected, the relevant block will be instructed to blink its red LED to let the programmer know where the problem is.

And that is pretty much all there is for now. The blocks are really only "dumb" placeholders and all the smarts lives in the Master Controller.

Postscript:

Since the successful completion of this initial prototype I have created some PCBs to build some more permanent, robust modules. I have also been giving some thought to how I would improve the code. I have also given some detailed thought into how I could improve the hardware. On the hardware front, I am still using Arduino Pro Minis (they are dirt cheap) but I am considering making custom boards based on either the Atmega328PB or ATTiny841 chips. These chips have two hardware serial ports, which will make the bi-directional communication easy and are relatively inexpensive. Moving the ATTiny841 would mean I will have to move away from a single codebase for all block types, as the size of the code is becoming a bit too large to fit in such a small device. I don't think this will be a huge problem - the communications protocol is already in a library, so I could create a library for the common module operations so I am not doubling up on too much code.

One big software change I want to implement is I want to flip the program execution on its head and have the blocks take control of their own destiny - calculating values and updating the Master Controller as appropriate. The blocks could pass an "Execution Token" around to indicate which block is currently executing. The output could be handled by having an Output Controller, which has an attached display. Each Output module would then send a message to the output controller, telling it what to output. Similarly, an "Input Controller" could be added, allowing for user input via a keypad or other device. This would allow for interactivity during program execution.

When I get some spare time I will be playing around with my first (and second) batch of PCBs and will update my explorations, however I am about to start a new semester at university, so free time may be a bit tight for the foreseeable future...

Discussions