Click here to Skip to main content
15,867,983 members
Articles / Programming Languages / C#

Introducing BBC micro:bit and MakeCode blocks .. with a Toy Robot Car and PC

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
9 Nov 2020CPOL23 min read 10.3K   119   5   4
Introduction micro:bit and hobby example. Several Remote Controls (Infrared, Bluetooth Android App, serial port PC)
In this article, you will see a short introduction to micro:bit and programming in MakeCode blocks or switch to "JavaScript/Python". V 2.0 of micro:bit announced. You will be introduced to a toy robot car (Maqueen) and ESP 32 camera as extra hardware. Use of several remote controllers are discussed: Infrared, Bluetooth with Android app, Radio with 2nd micro:bit with tilt as controller, PC C# program with serial port using BlockingCollection and reconstructing lines.

Table of Contents

Introduction

In 2016, BBC started delivering the micro:bit board free to every 11-year-old kid in Britain. The board has a reset button, 2 user Buttons, 5*5 Leds, accelerometer, primitive compass and temperature sensors, Bluetooth BLE and can be connected to a PC using a USB cable. It has some popularity in the area of STEM education.

Now the compatible new micro:bit version 2 is announced, it is a good time to mention and introduce on Codeproject the micro:bit and the MakeCode programming with code blocks (or switch to "JavaScript/Python") to program it. The introduction will be very short because good documentation for both is already available.

To show what is possible with the rather basic micro:bit and to raise some interest for some recreational lite hardware "programming", I will introduce and shortly discuss some extra hardware I have bought: a mini robot car (Maqueen lite, may robot cars are available) and for future projects a cheap ESP32 cam that can act as a WIFI streaming web server.

Next, I will shortly mention some standard mini projects I did on remote controls: using Infra Red DVD remote controller, using Bluetooth with an Android Bluetooth App and finally using a 2nd controller micro bit for radio communication (controller micro:bit: use tilt or 4 push buttons on a bread board).

I have gathered some development samples just as they are of .hex files for MakeCode, but they are just to give an idea, it is more fun to find things out yourself. Same holds for the described hardware, many other options are possible.

Finally, I will discuss to use a PC for remote control with the extra micro:bit connected to the PC. Direct Bluetooth did not work at the first try, to do. I will discuss a first sketch of this control program. For the serial port communication, I copy the sequence of strings from port.ReadExisting to a queue of BlockingCollection<string> and I will give a code snippet to reconstruct the original text lines from the arbitrary segmented lines.

My hobby interest was shifting to do some "intelligent" processing on a W10 PC, but the power supply for the camera with 2 batteries is doubtful now. So for now, this is all fantasy and it will take some time before something happens if we say "Robot Forward" or even "Robot bump to a red ball in the arena"!!

Background

1.5 years ago, I bought a simple small toy robot car (only 2 wheels, no arms) with a micro:bit. It looked fun, reasonably affordable (Micro:bit less then 20 Euro, robot less then 30 Euro, no delivery costs picked up by bike) and feasible given my limited hardware knowledge.

Writing small "programs" in MakeCode block programming is very primitive and somewhat limited but simple and straightforward. Small standard programs supported by the hardware of the robot are IR remote control, line following, obstacle avoiding using the ultrasonic distance sensor, flashings Leds and playing tunes.

This year, I did a second iteration using as remote control a Bluetooth Android App from the PlayStore. I also tried to connect via Bluetooth to a W10 PC but this did not work directly. I switched over to an extra micro:bit connected to a PC for micro:bit to micro:bit radio communication.

Part of the fun is to browse sites selling hardware stuff but not to buy too much, hardware cost money. The E32 cam (12 Euro) with an Arduino Uno clone (7 Euro) to download the web-server program I just had to buy.... I mean of course that this was a rational decision in line with my future hobby plans...

Looking at the remote control work and the availability of the new Huygens camera (some AI learning by the camera, detections accessible in MakeCode program), new goals for the hobby project emerged. The hobby plans were shifting to do some intelligent processing at the good old W10 PC C# environment, but given the battery problems for the ESP 32 camera, I have to rethink that.

BBC micro:bit

I will keep the introduction very short, you can find everything over the micro:bit here. To give an impression of the micro:bit V1.0, see figure 1 for the USB port, buttons, Bluetooth and sensors on board.

Image 1

Figure 1. BBC micro:bit V1.0 sensors on board.

It has a solid edge connector. See figure 2 for the available Pins.

Image 2

Figure 2. Pin layout.

The micro:bit costs about 20 Euro. If you ask me, should I buy this board? My answer is NO,NO,NO!
.. buy the newly announced BBC micro:bit V2.0, compatible with the V1.0., about same cost.

Several improvements are added like a microphone, speaker, touch button, sleep mode (special request from teachers temporary stop the sound of many beeping projects in classes), nodged edge connector better fit for crock clips.

According to micro:mag website:

"The processor has received a big upgrade (nRF52833), flash memory doubled to 512Kb, RAM has gone from just 16Kb to 128Kb. It should enable people to run more demanding tasks like AI and Machine Learning, something the Micro:bit Educational Foundation will be working on for release next year."

Anyhow, important improvements since I have had to (especially with Bluetooth programs) shorten some programs because they were too large for memory.

B.t.w., if you consider buying hardware look of course also at the good old more hardcore hardware Arduino stuff, many Groove sensor boards and kits, libraries and CodeProject articles.

Programming with MakeCode

Well, there are, of course, a lot of options to program the micro:bit, see here. One important alternative worth mentioning is of course the Arduino IDE (also available in Windows store), see instructions here.

However, here we will program the micro:bit connected with a USB cable to the PC and using the MakeCode editor. The MakeCode editor can be downloaded from the Windows store or you can just open the editor now as web page and try it here at makecode.microbit.org. See figure 3 for an impression. I will only mention a view properties, discover it yourself.

Image 3

Figure 3. Impression of MakeCode editor. Webpage or Windows store.

In the middle column, several extensions are grouped. In figure 2, the basic group is selected and we see we can select the show Leds block to drag to a block right. At the bottom, we can use the option advanced... add extensions to search for extra extensions and add these to the project. In the sample, the Maqueen robot extension is added. It is possible to write extension and store these on Github.

In the left column, we see the simulated micro:bit (buttons can be pressed), and because a servo statement is added, it shows a servo. The download button downloads the current code (a .hex file) to the micro:bit attached to the PC with a USB cable. If an external extension is added to the program, an explorer button of the elements in the .hex file is shown. If the downloaded program executes a serial write instruction, a console button is shown (for the simulated and the connected hardware micro:bit). In this way, the serial communication is shown, all named variables with serial write value are also plotted in time.

In the left column, we see the code blocks. The placements of the blocks is not fixed and organization in the 2D plane can become a little bit complicated. The latest update allows using the context menu to collapse all main blocks and expand them individually.

Programming with Blocks is straightforward, but a little bit tedious. An important option is to switch between Blocks and JavaScript/Python (if programs compiles). For example, define one variable, function or if statement in blocks, switch to JavaScript and do the rest there. I always place the comments here. Also inserting code or comparing code must be done using JavaScript/Python text. Switching to and from Blocks however can shift the comments or the order of variable definitions.

There are some new debug options, I often use serial write statements in code and look in the console. It is also possible to show temporary icons, single characters or moving strings using the 5x5 Leds or if a robot with speaker is present to make a sound, play a melody at the start of a program.

In general, all works straightforward as long as no common hardware is used like shared Pins, radio/Bluetooth extensions are exclusive, a common timer in servos and music, etc.

Extra Hardware: Maqueen Lite Robot

There is a lot of additional hardware available from groove sensor boards to robot arms. There are also a lot of toy mini robot cars on the market, see for example here or here. I have bought without much consideration a Maqueen lite V 3.0, see figure 4. In retrospect, it is also possible to build such a robot car from scratch at the cost of some extra time. A good power supply for servos and camera seems important.

Image 4

Figure 4. Maqueen Lite robot car.

Out of the box, it has 2 motors, a battery holder with on/off switch, a Ultrasone distance sensor (the 2 "eyes"), a buzzer, RGB ambient Lights, an Infrared receiver, 2 Infrared Gray scale sensors for line following at the bottom, M3 Screw Hole x6 for attaching larger mounts

This year, I saw some new products, Maqueen lite V 4.0, a more expensive Maqueen plus (extra battery and charger needed), a mechanical add-on with 2 servo motors for it and a HUSKYLENS. For the Maqueen lite 3.0, I cannot recommend a servo motor, start by trying 1 (Auxiliary Power to the Servos?)

The HUSKYLENS (with an IPS interface for training) is an interesting concept. It claims to support recognition/detection of faces, objects, tags, colors, etc. As I understand it, now it is hardware connected (UART, IC2) to the robot and makes detections available by events in code (MakeCode support??). The price of the Huskylens is for my hobby profile too serious, however it made me think about doing more intelligent processing in my own C# PC development environment.

Extra Hardware: Cheap ESP32 Camera

The ESP32 cam is a (future) project on itself. The camera board itself cost only 12 Euro, but additional costs are much higher. I will discuss it here now because it could lead to the way of doing more intelligent processing on a PC.

Low power ESP32 boards support often integrated WIFI and Bluetooth, have some processing power and can be programmed using the Arduino IDE. This board can be programmed to act as a WIFI webcam streaming web server to create a visual flow from robot to PC.

Initially, we could show the stream in a C# program using the URL using WebView or the new WebView2 (now production ready). The idea of a camera is attractive, see what the robot see, look around, etc. Remote navigation in a simulated moon (optional with delayed sampled images) or Lego landscape.

In a later stage, we could sample images and do some more intelligent processing and give commands to the robot. The image quality is not very good (better sensors make intelligent tasks easier), but we can control the environment and do only simple specific tasks. For example, decode 4 stacked lego blocks of different colors, basic shapes or barcodes. After the intelligent processing, we can send commands back to the micro:bit.

The ESP32 cam board can be programmed using the Arduino IDE on a PC, but it has no USB. There are special USB sticks/boards to do that, but since the cost for a cheap Arduino Uno clone was the same, I used an Arduino.
See for example electroniclinic for the wiring scheme electroniclinic, I followed the instruction in this video. On the experimentation board with USB powered Arduino, everything works ok.

Image 5

Figure 5. Wooden Board. Left half for ESP32 cam programming using Arduino.

Note that I have heard that a WIFI web-servers can form a security risk. I glanced at the C code of the sample, as I understand it from here uses this for face detection. For me, this goes beyond a simple hobby project, but in theory, some intelligent processing at the camera is possible. Maybe I can adapt the streamed html page.

For the mount of the ESP 32 cam on the robot, you can use M3 copper bolts (1-3 cm) which have also screw holes at the other side. The camera fits to a 170 pins breadboard. The big challenge appears to be to power the camera with 2 or 3 batteries. On the experimentation board, it always works. Initially, it seemed to work on 2 chargeable batteries, but now it appears to work random but often not. ESP 32 boards seems to have low power consumption but initial burst of current. Yesterday, I tried 2 lithium batteries as recommended with no success.
I have to rethink the camera costs and if this forms a good basis for future projects. It may be too ambitious given my limited hardware capabilities and interests. For real hardware experts, I suppose it is a piece of cake to select capacitors, boosters and power supplies.

Remote Control Samples

I will now shortly mention a few remote controllers, to show what the hardware of the robot + micro:bit(s) are capable of. First, we will use the infrared from the robot, then the Bluetooth with an Android App and finally radio between 2 micro:bits and the tilt of the controller micro:bit. The .hex files that can be downloaded in MakeCode of these 3 cases are in the first zip file you can download. The fun for me is in thinkering, not playing a lot with the slow moving robot. Credit to a dutch site where I downloaded a parcours for testing the line follower and I copied the computation of the tilt to motor speed and the idea of flag the state of the morors by setting only a few of the 5x5 Leds fast. Also mentioning strawbeeds, common hardware timer of servos and music, etc.

Infra Red using Old DVD Remote Controller

Infrared is an easy way to provide a larger number of manual options but not the best for continuous control. Often, an old IR remote controller is already in the house, for example, an old TV, DVD or intelligent lamp.

In MakeCode, use Advanced option... Add external extensions and search for Maqueen. If you do that now, you will notice 2 extra extensions in the middle row: Maqueen IR and Maqueen (green). See figure 6 for the available blocks.

Image 6

Figure 6. Options in green Maqueen extension.

For the IR, we will use blocks "On IR received" and "read IR key value" blocks. In the downloads, we have added a sample .hex file as it is. Robot forward will stop after a short burst for debugging, except for options line following and obstacle avoidance. For line following design your own lines and print it, or download Parcours.pfd bottom of this page. Comments in the long IR code if list are visible in JavaScript option (in Dutch). You have to discover the IR codes for your IR remote controller yourself and adapt the program. This can be done by activating the serial writes or the show number command for the Leds (this takes time, extra pause, multiple characters text scrolls). Note that the robot must be on for the IR sensor to work, the USB connection must be attached for the console option to appear after serial writes has occurred.

Bluetooth, Using Android Kitronic move App

At home, I have a potential Bluetooth remote controller, an Android tablet. The micro:bit has Bluetooth BLE capabilities. Martin Woolley helped develop the Bluetooth profile for the micro:bit V1.0. He published some free Android programs for accessing the BLE services of the micro:bit like the 5x5 LED matrix. His remote controller app is a paid app I believe so I will discuss here the free Kitronic Move App from the Google Play Store.

Install the App, pair the micro:bit to the tablet/phone, scan in the app for a Micro:bit, select it and use the game app touch buttons. See the video. If it fails, repeat process, remove and restore optionally pairing tablet/micro:bit. When the app has connected to the micro:bit control is good.

C#
function computeSpeed () {
    // Speeds are Weighted sums dep. buttons pressed. To do in forward+l/r more spin
    M1Speed = 80 * btnA - 60 * btnB - 40 * btnC + 40 * btnD
    M2Speed = 80 * btnA - 60 * btnB + 40 * btnC - 40 * btnD
}

control.onEvent
(EventBusSource.MES_DPAD_CONTROLLER_ID, EventBusValue.MICROBIT_EVT_ANY, function () {
    // A Forward
    // B backward
    // C Left
    // D Right
    if (control.eventValue() == EventBusValue.MES_DPAD_BUTTON_A_DOWN) {
        btnA = 1
        basic.showArrow(ArrowNames.North)
    } else if (control.eventValue() == EventBusValue.MES_DPAD_BUTTON_A_UP) {
        btnA = 0
        basic.clearScreen()
    } else if (control.eventValue() == EventBusValue.MES_DPAD_BUTTON_B_DOWN) {
        btnB = 1
        basic.showArrow(ArrowNames.South)
    } 
    .... all buttons handled similar way
    }
    // we can always update speed with current button state
    computeSpeed()
    ....
Figure 7. JavaScript snippet for Bluetooth controlled robot

In MakeCode, use add extension and add Bluetooth. Notice that the radio extension has now gone because it uses the same hardware. See figure 7 for a code snippet, this time in JavaScript. We use the Bluetooth button event send by the App to update the state of the buttons and compute the motor speed as a weighted sum of the 0/1 values of the buttons. Multiple buttons like Forward and Left can be simultaneously pressed. If this administration is out of sync, repeat button presses. Note that showing the Compass Arrows in the 5*5 Leds cost some pause time, press the buttons some time. The .hex file is again included in the zip download.

At this point, I got the idea of using the PC as a Bluetooth controller. I compiled and run some UWP Bluetooth BLE samples. The micro:bit is listed, but cannot be connected to. Solving this problem could be a quick fix [Adapt Bluetooth com port, Bluetooth settings in MakeCode, Can the profile be set using the explorer button in MakeCode] or a lot of work [Arduino Bluetooth to PC must exist, use Arduino IDE to add an extension or use Arduino IDE and not use MakeCode at all for the Robot car]. I choose to do first a guaranteed solution, add a 2nd micro:bit for radio communication and connection to a PC using a serial port, to be discussed in the PC controller later.

Remote Control : Radio with 2nd micro:bit, 4 Breadboard Buttons or Tilt

Image 7

Figure 8. Extra micro:bit for radio control on a board. Select tilt or use push buttons.

What is more programming fun than 1 micro:bit, well a 2nd micro:bit for radio communication, of course. There are game pads with buttons designed for a 2nd micro:bit, but that does not quite fit my hobby profile. From a project 8 years ago, I had a breadboard and some buttons. I bought a plug from micro:bit controller to breadboard to connect to the bread board buttons. With button B, you can switch from using the breadboard push buttons or to use the tilt or proportional tilt of the controller micro:bit, so the breadboard is optional. You can also opt for a joystick instead of push buttons. If you use tilt and don't want to use the USB cable for power supply, you can buy a small power board that you can connect to the micro bit.

So we have a robot micro:bit (1) and a controller micro:bit (2), so we have 2 different programs with radio communication. For details, see again the .hex files in the first Zip file. In a new project, the Radio extension is always present. Let's do this robot dance using Tilt.

The robot receiver program (1st program) is very simple. First, a radio group is selected, we choose 5, must be the same in the controller program. The onRecievedValue events are used to set the Motor speeds, these are used in a forever loop later to set the motor speeds using Maqueen.motorRun. Here, single Leds are turned on to have a visual indication of the motor speeds without a robot. No error correction or safeguards on speed are used. Note that it will only process values labeled as "sL" and "sR", acronyms for motor speed Left/Right.

C#
radio.onReceivedValue(function (name, value) {
    // serial.writeValue(name, value)
    if (name == "sL") {
        mLSpeed = value
    }
    if (name == "sR") {
        mRSpeed = value
    }
})
Figure 9. Received Values are used to set Motor speeds.

The radio controller program (2nd program) computes the motor speeds and radios them to the robot program. The controller program has 3 modes/choices, that can be selected using Button B of the micro:bit. First mode is using the buttons on the breadboard. The buttons only have to connect to the ground. B.t.w., there are only 3 Pins free, but button A press can also be invoked by using a breadboard button on its Pin. Computing speed from the button state works similar as in the Bluetooth App controlled sample. The two other modes use the Tilt of the controller micro:bit. The tilt to speed computation was copied from the previous mentioned site.

Remote Control: PC C# Program with Extra micro:bit

As discussed, our first try was using the Bluetooth connection to the PC directly, but we could not connect to the micro:Bit, this can be explored later. We describe here the approach that resulted direct in success although the hardware setting is a little more complex and requires an extra micro:bit. The C# program is first prototype. Source code of the .hex files and C# is in 2nd Zip.

The setting is that we have a micro:bit and radio receive program for the robot (1). Next, we have a micro:bit and program for the controller (2). This program radios to the robot and receives commands from the PC over a serial port using a USB cable. And finally, we have a PC program C# with some buttons (3).

The robot program (1) is the same as the previous robot program. It listens to the radio to speed commands (figure 9) and sets the motor speeds.

The micro:bit controller (2) radios speed commands to (1) using the MakeCode radio extension, already tested. The speeds however are determined by the commands from the PC (3) using the MakeCode serial extension. At this point, no communication from the controller in the direction to the PC is needed but for future use and for testing, this is also added. We will use lines terminated by <CR> and <LF>.

The controller program sends with 2 second intervals a string with number 0..9 to the PC program over the serial port. If the C# program makes connection to the port, it will show these strings as proof that the connection is successful. For debugging, the controller sends received strings back to the C# program with some extra header and tailer characters. If it receives a command, it radios it to the robot program, but also sends the string back with different header and tailer characters to the PC. Radioing the received lines directly to the robot did not work. I decided for now not to change the robot program, but the controller (2) interprets for now the received lines and radios the result in the tested way with radio.writevalue("sL",mSpeed).

Note again for the simple remote control we use no protocol or error correction. We also do not catch any IO errors, not studied yet. We tested it by visual inspection of the received strings in program (3) and finally used the buttons (not much mileage). I did not do a thorough test with generating a text file, do sends / receives and finally compare the files.

Image 8

Figure 10. Initial PC controller interface. Focus now handling Serial Port communication

We will first describe the PC program (3) and then zoom in on the serial port code. See Figure 10 for UI. Left column for connecting to a port, send a string and show received data. Select a port, use the open button. If successful and micro:bit controller connected, we see every 2 seconds a received test string. Strings can be sent by pressing the Send button. See in code discussion in case of errors connecting to port: stop other programs using the port, optionally connect USB cable again. The "arrow" buttons send speed commands to the controller. The fake image could in a far future be replaced by a WebView showing the URL of a streamed web cam server. The program can be improved by showing more information then the name in the port list. For experimenting, auto connection to a default port could be introduced.

We have a ViewModel without commands but we will use mainly code behind for this prototype. The serial port stuff is placed in a different file. We will now zoom in on a few aspects of the serial port programming. At first thought, there are several scenarios for incoming data: Continuous (async) read in separate thread/process, use a Timer and reading regularly or react on an event when data comes in.

Note in the following that I do know nothing about threads, tasks, async stuff or serial ports. I have combined some samples and it seems to work, please report improvements. I have chosen to use the SerialPort.DataReceived event, see Figure 11. ReadExisting() is buffered and should not leave a character behind. Can a new event be called when an older event is being handled, can we use a semaphore WaitOne() in this scenario for blocking this?? For now, I dump the received bytes a.s.a.p. in a BlockingCollection<string> queue and call the QueueToLines using a Dispatcher.Invoke. The Dispatcher.Invoke cannot be placed in the ViewModel so the Receive event must always be defined in code behind in MainWindow.xaml.cs.

C#
public BlockingCollection<string> queue = new BlockingCollection<string>();

private void Receive(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
  if (MainVm1.NotOpen) return;

  // Collecting the characters received to our 'buffer' (string).
  // ReadExisting buffers so not missed chars if no Errors
  string received = MainVm1.sp.ReadExisting();
  MainVm1.queue.Add(received);
  Dispatcher.Invoke(DispatcherPriority.Send, new MainVm.UpdateDelegate(MainVm1.QueueToLines));
}
Figure 11. Port DataReceived event defined in code behind

The OS determines when the event is called, so lines are arbitrary segmented in received strings. A queue entry can consist of Multiple lines can or truncated line parts. Figure 12 gives a code snippet to reconstruct the original lines and put them in RecievedLines that are shown in the interface.

C#
public void QueueToLines()
{
    string item1;
    string combi = leftover;
    leftover = "";

    while (queue.TryTake(out item1)) { combi = combi + item1;}

    if (combi.Contains("\n"))
    {
        string[] lines = 
           combi.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
        int i = 0;
        foreach (var line in lines)
        {
            if (i == lines.Count() - 1)
            {
                // is the last line termiated by /n??
                if (combi[combi.Length - 1] == (char)'\n')
                {
                    RecievedLines.Add(line);
                    leftover = "";
                }
                else
                {
                    leftover = leftover + line;
                }
            }
            else
            {
                RecievedLines.Add(line);
            }
            i++;
        }
    }
    else
    {
        // collect leftovers until we have a sentence /n ...
        leftover = leftover + combi;
    }
}
Figure 12. Code snippet to reconstruct lines from arbitrary segmented queue strings

Future Plans, Intelligent Processing in C# on W10 PC??

Publication is a little bit premature but I wanted to mention the newly anounced V2.0 of the micro:bit at CodeProject. There are 2 things I had planned.

  • Add speech commands to PC control program. Not because it is practical or useful (otherwise speech controlled buttons would be available in XAML), but because it is cool to move a robot this way. I belief Microsoft had a special SDK for speech recognition and now it is in Azure cognitive services.
  • We have skipped direct Bluetooth communication from micro:bit to PC, but we could take a 2nd look at it.

Theoretically, a web cam server provides a visual flow from the robot car to the PC. We can see on a web page what the robot camera sees. Inspired by the ESP 32 cam board, I wanted to do more intelligent processing in my good old Windows PC environment. Modifying the camera program seems possible, but not my expertise. A simple task could be the discovery of stacks of four Lego blocks with different color encodings, detect basic geometrical forms or barcodes.

The ESP 32 camera works fine in the development board (USB cable - Arduino - ESP board) but not with 2 batteries for attaching it to the little robot car. Experimenting and buying capacitors, compact boosters or power supplies is a little bit out of my hardware capabilities and hobby ambitions, so I have to rethink what my next steps are.

History

  • 9th November, 2020: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Netherlands Netherlands
Retired hobby programmer.

Comments and Discussions

 
QuestionProgram download Pin
Anskim6-Dec-20 5:45
Anskim6-Dec-20 5:45 
AnswerRe: Program download Pin
wim4you8-Dec-20 3:50
wim4you8-Dec-20 3:50 
QuestionThe Title Pin
_Nizar9-Nov-20 20:05
_Nizar9-Nov-20 20:05 
AnswerRe: The Title Pin
wim4you9-Nov-20 22:36
wim4you9-Nov-20 22:36 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.