Introduction: Worldwide Microcontroller Link for Under $20

Control your home thermostat from work. Turn on a sprinkler from anywhere in the world by flicking a switch. This Instructable shows how to link two or more $4 microcontrollers using the backbone of the internet and some simple VB.Net code.

This builds on an earlier Instructable which shows how to link a microcontroller to a PC and use a pot to control a servo https://www.instructables.com/id/Control-real-world-devices-with-your-PC/ This time we have a microcontoller talking to a VB.Net program then to an ftp website, back to another VB.Net program and thence a second microcontroller anywhere in the world, with or without human intervention.

How else are the machines in The Matrix ever supposed to take over if they can't talk to each other?

Step 1: Gather the Parts

Many of the parts are the same as in the PC Control Instructable https://www.instructables.com/id/Control-real-world-devices-with-your-PC/ and it is suggested that this be completed first before attempting to link two microcontrollers. While it is quite possible to use a pot to control a servo, this time round we are going to go for something simpler - a switch turning on a led. The switch could easily be a tank level sensor and the led could be a pump down near a river but let's get something simple working first.

Parts - Two Picaxe 08M chips - available from many sources including Rev Ed http://www.rev-ed.co.uk/picaxe/ (UK), PH Anderson http://www.phanderson.com/ (USA) and Microzed http://www.microzed.com.au/ (Australia). These chips are under $4US.

Two of: Protoboard, 9V battery and battery clips, 10k resistor, 22k resistor, 33uF 16V capacitor, 0.1uF capacitor, 7805L low power 5V regulator, wires (solid core telephone/data wire eg Cat5/6), LED, 1k resistor.

1 of: D9 female socket and cover and 2 metres of 3 (or 4) core data wire (for download) and a toggle switch.

2 computers with 9 pin serial ports (can be debugged on one computer though) and an internet connection.

For computers with no serial port, a USB to serial device http://www.rev-ed.co.uk/docs/axe027.pdf and a small stereo socket.

Step 2: Download and Install Some Software

We will need the free VB.Net and the picaxe controller software and if you have done the PC controller Instructable you will already have these.

VB.Net (Visual Basic Express) is available from http://msdn2.microsoft.com/en-us/express/aa718406.aspx

The picaxe software is available from http://www.rev-ed.co.uk/picaxe/

You will need to register with microsoft to get the download - if this is a problem use a fake email or something. I actually found it helpful giving my real email as they send occasional updates.

I'm also going to mention the picaxe forum http://www.picaxeforum.co.uk/ as this is the sort of forum staffed by teachers and educators and where students can usually get answers to questions within a few hours. The forum is very understanding of even the simplest questions as some of the students are still at primary school level. Please don't be scared to ask for help!

Step 3: Build a Download Circuit

This download circuit uses a picaxe chip, a couple of resistors, a regulator and a 9V battery. More information is available in the picaxe documentation/help which comes up in the help menu of the program. The circuit should only take a few minutes to build once all the parts are to hand. Once a chip is programmed it retains its program in EEPROM even when the power is turned off. Since we are programming two chips it might be worth labeling the chips so you know which is which. You can always go back and reprogram a chip by removing a link and moving a resistor.

I might also add that picaxes do run happily on 3 AA batteries. A 5V regulated supply is useful for running analog inputs as the reference voltages don't change, but for simple on/off circuits a regulated supply is not needed. The 5V reg can be left out in these situations.

Step 4: Program the Chips

We will call one program Tx and one Rx. Tx is the controlling chip and has a switch and a led. Rx also has a led. When the switch changes the signal goes from Tx to Rx, changes the led and also changes a second variable which then goes back to Tx. So flick the switch and in less than a minute the led changes on both circuits indicating that the message got there and the Rx is acting on the new switch position.

At the simplest level the picaxe has 14 single-byte registers. When a virtual network is created we link all those registers together so if a byte changes in one picaxe it changes in all the picaxes. Clearly if two picaxes are trying to change the same byte then it will get very confusing but if each picaxe only changes one byte then all the other picaxes can see that change and can act on it. Simple messages can be passed back and forward if a certain byte is only changed by one picaxe. A pot can change the value in a register and one or more other picaxes can sense that change and move a servo or whatever and turn on a heater. A second register could send back the temperature in the room.

Copy and paste the programs in turn into the picaxe programmer and download them to each of the respective chips using the blue download arrow from within the picaxe programmer.

Tx:

main:serin 3,N2400,("Data"),b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13' get packet from computer
if pin2=0 then' test the switch and set register b0 depending on status
b0=0
else
b0=1
endif
if b1=0 then' other picaxe sets b1 depending b0
low 1' led off
else
high 1' led on
endif
serout 0,N2400,("Data", b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13)' send back to computer
goto main

and Rx:

main:serin 3,N2400,("Data"),b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13' get packet from computer
b1=b0' change register b1 to equal register b0
if b1=0 then
low 1' led off
else
high 1' led on
endif
serout 0,N2400,("Data", b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13)' send back to computer
goto main

Step 5: Build the Tx Circuit

If you are flipping back and forth between a working circuit and a programming circuit be sure to change the connection to leg 2 and the location of the 22k resistor from leg 2 to leg 4. Or you can build a dedicated download circuit and move the chips across. Just note whether a circuit is running or downloading as it can get quite confusing. In particular, note that a running circuit will not work if leg 2 is left floating - it needs to be grounded. Leg 2 is the download pin and if it is left floating it picks up stray RF from flouro lights and the chip thinks another program is being downloaded.

It is also worth mentioning picaxe nomenclature which calls a physical pin a leg and a virtual pin a pin. Thus an output on pin 2 in code is actually an output on physical leg 5. This might seem strange but it means that code can be ported to bigger picaxes like the 28 and 40 pin versions and still work.

Step 6: Build the Rx Circuit

This circuit is almost the same as the transmitter - it just has no switch.

Step 7: Write Some VB.Net Code

I could have compiled the code and made this program available as a compiled .exe but learning some VB.Net is so incredibly useful that it is worth going through it step by step. If you are running this on two different computers you can Build the program into an .exe which creates a little setup program which can be installed on the second computer. Or you can put VB.Net on both computers and run the programs from within VB.Net

Let's assume you know how to open a new VB.net project from step 7 and 8 of https://www.instructables.com/id/S1MMU2XF82EU2GT/

On the blank form let's add the following components from the toolbar and put them on the form in the locations as shown. For the labels and the textboxes, change the text property (over on the lower right) to what is needed. Don't worry about the settings for the timer - we will change them in the code but do make sure to put a timer in. You can move things around and there are no real rules about location. The big text box is a RichTextBox and the smaller three are ordinary Textboxes. In terms of order we are starting at the top of the form and moving down. If you leave something out there will be an error in the code which should give some sort of clue.

Please pick a random filename for Textbox3 - this is the name of your unique group of picaxes on the ftp server and obviously if we all use the same name then data is going to get all muddled!

Sorry about the dashes in this table - putting in spaces loses the formatting in the table.

Toolbox object-------Text-----------------------------------------Notes

Label1------------------Picaxe Communications
Label2------------------FTP Status
Label3------------------Status
Label4------------------Picaxe Registers
Label5------------------Register 0-13
Label6------------------Value 0-255
Label7------------------FTP link filename
Textbox1----------------0----------------------------------------------0 is a zero not an O
Textbox2----------------0
Textbox3----------------Myfilename-------------------------------Change so no clashes!
Button1------------------Modify
Richtextbox1
Picturebox1
Picturebox2
Timer1

Step 8: Add Some Code

See step 12 of the other instructable for the location of the button that flips between form view and code view. Switch to code view and paste the following code in. The colors should all reappear as in the screenshot . If a line hasn't copied properly due to a wordwrap problem then delete spaces till the error message goes away. I've tried to comment most of the lines so the code at least makes some sense. Delete the public class bit so the text is blank before pasting this - this code already has a public class. If an object like a text box hasn't been placed on the form or has the wrong name then it will come up in the text code with a squiggly blue line under it.

Imports System.IO
Imports Strings = Microsoft.VisualBasic ' so can use things like left( and right( for strings
Public Class Form1
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Integer) ' for sleep statements
Dim WithEvents serialPort As New IO.Ports.SerialPort ' serial port declare
Dim PicaxeRegisters(0 To 13) As Byte ' registers b0 to b13
Dim ModifyFlag As Boolean
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load ' need all this rubbish stuff - .net puts it in automatically when go form1events above/load
Timer1.Enabled = True ' put this in code as defaults to false when created
Timer1.Interval = 20000 ' every 20 seconds
PictureBox1.BackColor = Color.Gray ' start with the comms boxes gray
PictureBox2.BackColor = Color.Gray
ModifyFlag = False ' if modify a value manually then skip download
RichTextBox1.Multiline = True ' so can display more than one line
Call DisplayPicaxeRegisters() ' display the 14 registers
Call ReadFTPFilename() ' read the filename off the disk (resaved every 20 secs)
End Sub
Sub SerialTxRx()
Dim DataPacket(0 To 17) As Byte ' entire data packet "Data"+14 bytes
Dim i As Integer ' i is always useful for loops etc
For i = 0 To 3
DataPacket(i) = Asc(Mid("Data", i + 1, 1)) ' add the word "Data" to the packet
Next
For i = 0 To 13
DataPacket(i + 4) = PicaxeRegisters(i) ' add all the bytes to the packet
Next
If serialPort.IsOpen Then
serialPort.Close() ' just in case already opened
End If
Try
With serialPort
.PortName = "COM1" ' Most new computers default to com1 but any pre 1999 computer with a serial mouse will probably default to com2
.BaudRate = 2400 ' 2400 is the maxiumum speed for small picaxes
.Parity = IO.Ports.Parity.None ' no parity
.DataBits = 8 ' 8 bits
.StopBits = IO.Ports.StopBits.One ' one stop bit
.ReadTimeout = 1000 ' milliseconds so times out in 1 second if no response
.Open() ' open the serial port
.DiscardInBuffer() ' clear the input buffer
.Write(DataPacket, 0, 18) ' send the datapacket array
Call Sleep(300) ' 100 milliseconds minimum to wait for data to come back and more if data stream is longer
.Read(DataPacket, 0, 18) ' read back in the data packet array
.Close() ' close the serial port
End With
For i = 4 To 17
PicaxeRegisters(i - 4) = DataPacket(i) ' move the new data packet into the register array
Next
PictureBox1.BackColor = Color.GreenYellow ' working
Catch ex As Exception
PictureBox1.BackColor = Color.Red ' not working
End Try
End Sub
Sub FTPUpload(ByVal Filename As String)
Dim localFile As String 'place to store data
Dim remoteFile As String ' filename is case sensitive this is really important
Const host As String = "ftp://ftp.0catch.com" ' note the 0 is a zero not a character O
Const username As String = "picaxe.0catch.com"
Const password As String = "picaxetester"
Dim URI As String
localFile = Filename ' maybe not needed but if define a location eg c:\mydirectory can add easily this way
remoteFile = "/" + Filename ' file on ftp server needs "/" added in front
URI = host + remoteFile
Try
Dim ftp As System.Net.FtpWebRequest = CType(System.Net.FtpWebRequest.Create(URI), System.Net.FtpWebRequest)
ftp.Credentials = New System.Net.NetworkCredential(username, password) ' log in
ftp.KeepAlive = False ' will be disconnecting once done
ftp.UseBinary = True ' use binary comms
ftp.Timeout = 9000 ' timeout after 9 seconds - very useful as ftp sometimes dies
'timeout (and the clock frequency of 20 secs) may need to be slower for dialup connections
ftp.Method = System.Net.WebRequestMethods.Ftp.UploadFile ' start sending file
Dim fs As New FileStream(localFile, FileMode.Open) ' open local file
Dim filecontents(fs.Length) As Byte ' read into memory
fs.Read(filecontents, 0, fs.Length)
fs.Close() ' close the file
Dim requestStream As Stream = ftp.GetRequestStream() ' start ftp link
requestStream.Write(filecontents, 0, filecontents.Length) ' send it
requestStream.Close() ' close the link
PictureBox2.BackColor = Color.GreenYellow ' change the box to green to say worked ok
Label2.Text = "FTP Connected" ' text saying it connected
Catch 'can't connect
PictureBox2.BackColor = Color.Red ' box to red as no connection
Label2.Text = "FTP Upload Fail" ' text saying connection failed
End Try
End Sub

Sub FTPDownload(ByVal Filename As String)
' downloads remotefile to localfile
Dim localFile As String 'place to store data
Dim remoteFile As String ' filename is case sensitive this is really important
Const host As String = "ftp://ftp.0catch.com"
Const username As String = "picaxe.0catch.com"
Const password As String = "picaxetester"
Dim URI As String
'localFile = "C:\" + Filename ' store in root directory but can change this
localFile = Filename ' so can add c:\ if need to define actual location
remoteFile = "/" + Filename ' added to remote ftp location
URI = host + remoteFile ' make up full address
Try
Dim ftp As System.Net.FtpWebRequest = CType(System.Net.FtpWebRequest.Create(URI), System.Net.FtpWebRequest)
ftp.Credentials = New System.Net.NetworkCredential(username, password) ' log in
ftp.KeepAlive = False ' will be disconnecting after finished
ftp.UseBinary = True ' binary mode
ftp.Timeout = 9000 ' timeout after 9 seconds
ftp.Method = System.Net.WebRequestMethods.Ftp.DownloadFile ' download a file
' read in pieces as don't know how big the file is
Using response As System.Net.FtpWebResponse = CType(ftp.GetResponse, System.Net.FtpWebResponse)
Using responseStream As IO.Stream = response.GetResponseStream
Using fs As New IO.FileStream(localFile, IO.FileMode.Create)
Dim buffer(2047) As Byte
Dim read As Integer = 0
Do
read = responseStream.Read(buffer, 0, buffer.Length) ' piece from ftp
fs.Write(buffer, 0, read) ' and write to file
Loop Until read = 0 ' until no more pieces
responseStream.Close() ' close the ftp file
fs.Flush() ' flush clear
fs.Close() ' and close the file
End Using
responseStream.Close() ' close it even if nothing was there
End Using
response.Close()
PictureBox2.BackColor = Color.GreenYellow ' green box as it worked
Label2.Text = "FTP Connected" ' and text saying it worked
End Using
Catch ' put error codes here
PictureBox2.BackColor = Color.Red ' red box as it didn't work
Label2.Text = "FTP Download Fail" ' and message to say this
End Try
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
If ModifyFlag = False Then 'if user changed a byte then don't download
Label3.Text = "Downloading"
System.Windows.Forms.Application.DoEvents() ' so new label text displays
Call FTPDownload(TextBox3.Text) ' download remote file
Label3.Text = "Downloaded"
System.Windows.Forms.Application.DoEvents()
Call ReadRemoteFileToRegisters() ' save file numbers to the register array
Label3.Text = "Talking to picaxe"
System.Windows.Forms.Application.DoEvents()
Else
ModifyFlag = False 'reset the flag
End If
Call SerialTxRx() ' send to the picaxe and read it back
Label3.Text = "Sent and recieved from picaxe"
System.Windows.Forms.Application.DoEvents()
Call DisplayPicaxeRegisters()
Call SaveRegistersToLocalFile() ' save numbers to file
Label3.Text = "Uploading"
System.Windows.Forms.Application.DoEvents()
Call FTPUpload(TextBox3.Text) ' send back up to ftp site named as my name
Label3.Text = "Resting"
Call SaveFTPFilename() ' so reads in when restart
End Sub
Sub DisplayPicaxeRegisters()
Dim i As Integer
Dim registernumber As String
RichTextBox1.Multiline = True ' so can display more than one line in the text box
RichTextBox1.Clear() ' clear the text box
For i = 0 To 13
registernumber = Trim(Str(i)) ' trim off leading spaces
If i < 10 Then
registernumber = "0" + registernumber ' add 0 to numbers under 10
End If
RichTextBox1.AppendText(registernumber + " = " + Str(PicaxeRegisters(i)) + Chr(13))
Next ' chr(13) is carriage return so new line
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim i As Integer
' check out of range first
i = Val(TextBox1.Text)
If i < 0 Or i > 13 Then
TextBox1.Text = 0
End If
i = Val(TextBox2.Text)
If i < 0 Or i > 255 Then
TextBox2.Text = 0
End If
PicaxeRegisters(Val(TextBox1.Text)) = Val(TextBox2.Text) ' change the value
Call DisplayPicaxeRegisters() ' and refresh the display
ModifyFlag = True ' and next ftp link skip downloading
End Sub
Sub SaveRegistersToLocalFile() ' save register array in a local text file
Dim i As Integer
FileOpen(1, TextBox3.Text, OpenMode.Output) ' open the text file named in the text box
For i = 0 To 13
PrintLine(1, Str(PicaxeRegisters(i))) ' save 14 values
Next
FileClose(1) ' close the file
End Sub
Sub ReadRemoteFileToRegisters() ' read local text file into the register array
Dim i As Integer
Dim LineOfText As String
Try
FileOpen(1, TextBox3.Text, OpenMode.Input) ' read the remote file name
For i = 0 To 13
LineOfText = LineInput(1) ' read in the 14 lines
PicaxeRegisters(i) = Val(LineOfText) ' convert text to values
Next
FileClose(1)
Catch ex As Exception
FileClose(1) ' file doesn't exist so do nothing
End Try
End Sub
Sub ReadFTPFilename() ' so the name of the remote ftp file is the same next time this program is run
Dim LineOfText As String
Try
FileOpen(1, "FTPFilename.txt", OpenMode.Input) ' open the file
LineOfText = LineInput(1)
TextBox3.Text = LineOfText ' read the name
FileClose(1)
Catch ex As Exception
FileClose(1)
End Try
End Sub
Sub SaveFTPFilename()
FileOpen(1, "FTPFilename.txt", OpenMode.Output) ' save the remote ftp file name
PrintLine(1, TextBox3.Text)
FileClose(1)
End Sub
End Class

Step 9: Run the Program on Both PCs

Start running the program by clicking the green triangle at the top middle of the screen - the 'Start Debugging' button. Nothing will happen for 20 seconds and then the program will attempt to connect to the ftp server and will attempt to connect to the picaxe. The pictureboxes will either go red or green.

The ftp location is a free website and anyone can use this but you need to use a different ftp working filename (mine is DoctorAcula1) otherwise we could all end up with each other's data if we use the same filename! If you like you can eventually get your own ftp site - just change the ftp location, username and password in two places in the code from my 0Catch website. Most websites allow ftp. Multiple computers can access the same ftp file - the ftp fileserver sorts out in what order these happen. Occasionally there are data clashes or hangs and these seem to happen every 20 file reads. There is a timeout in the code if this happens so it returns no data rather than corrupted data.

Using a broadband connection with a 128kbs upload speed means a file upload takes about 3 seconds but sometimes up to 8 seconds, most of which is taken up in handshaking rather than data transfer. This sets the timer1 time of a minimum of about 20 seconds taking into account download, upload and chat with the picaxe. With very fast broadband you may be able to shorten the cycle time.

You can change a register manually within the VB program. If you do, the next timer cycle skips downloading from the ftp site and sends the new data to the picaxe and then reads it back and uploads it. The new data thus finds its way to all picaxes linked to this group. This is helpful for debugging and/or for linking PC software into the microcontroller hardware loop. Websites can also access the hardware loop using PERL script or similar to write a new file to the ftp site.

This screenshot was taken running the Tx chip, the switch was on and the register b0 = to 1 had been sent to the Rx chip which had then changed register b1 to 1 as well. The led was thus lit on both boards.

This is a trivial application but it is easy to turn on a 3.6Kw pump instead of a led. Some more ideas are at http://drvernacula.topcities.com/ including linking picaxes via solar powered radio links. With radio links plus the internet it is possible for 'The Machines' to reach into many corners of the globe.

There are some ideas around on the picaxe forum about taking this idea further and replacing the PC and ftp site with dedicated webserver chips that plug straight into a router. Clearly this would decrease the power consumption of a link. If you are interested in further discussions please post on the Intstructable comments and/or on the picaxe forum.

Dr James Moxham
Adelaide, South Australia

Step 10: Screenshots of Code

By request, here are a series of screenshots of the vb.net code with all the formatting in place. This code was actually copied back of this instructable and the formatting reappeared automatically. It would be better to copy and paste the text than try to read these pictures but these will be useful if you are in an internet cafe and can't install vb.net.

Step 11: Screenshot2

Screenshot 2

Step 12: Screenshot 3

Screenshot 3

Step 13: Screenshot 4

Screenshot 4

Step 14: Screenshot 5

Screenshot 5

Step 15: Screenshot 6

Screenshot 6