dspaedt
Posts: 28
Joined: Tue Jan 29, 2013 1:38 am

Control Raspberry Pi with another Program

Sun Feb 17, 2013 12:22 am

So here is the plan. I want to use my Raspberry Pi essentially as a micro-controller and a small netbook I never use as the HMI. I can write a Windows based program to run on the netbook in Visual Basic no problem. For the Raspberry Pi I'll write a program in Python that will handle all the inputs and outputs through the GPIO's.

What I'm confused about, can anyone push me in the right direction I what I need to do to make the talk to each other. I would prefer that they are connected via a hard wire. Here is the scenario.
1. The RPi is out in the garage all wired up ready to function.
2. I walk out, start the RPi and it auto starts the program I wrote in Python to handle all the I/O.
3. I boot up the netbook, plug it in via a USB cable (just an example I'll use whatever means works and/or is the easiest)
4. Start the windows program on the netbook and begin controlling the RPi and accepting feedback from the RPi

As an example I'd like to pass back and forth integers, reals and bools (digital). For example, if I click a button on the windows program it will send the right signal to the RPi to know I just clicked the "Turn on Light" button for example. And also, l'd like to take numbers back from the RPi. Let's say it has a temperature probe wired to it. I want the RPi to be able to send 72.4 back to the netbook to windows program.

Anyone have any ideas or link they can point me to on how I do this? Would a USB cable be the right means? The netbook has USB ports, a serial port and a standard ethernet port.

User avatar
Jim Manley
Posts: 1600
Joined: Thu Feb 23, 2012 8:41 pm
Location: SillyCon Valley, California, and Powell, Wyoming, USA, plus The Universe
Contact: Website

Re: Control Raspberry Pi with another Program

Sun Feb 17, 2013 3:24 am

You would probably find Ethernet to be the way to go given that you want to communicate between two completely different hardware and operating system platforms. USB cables have a length restriction of around 10 feet (longer is possible, but not by much and it requires careful wiring configuration) and both computers are configured as masters on their respective USB buses, which is a big no-no for inter-system communication.

Ethernet communication is via software "sockets" which are opened similarly to opening a file for reading or writing (i.e., receiving and sending data over the network). Network data packets are then exchanged by writing and reading data to/from the sockets on each system. You probably want to use a slot-value protocol where each piece of data has its data type sent, followed by the data value, e.g., temp=72.4. This assumes you exchange ASCII strings and then convert the data to int, float, etc., as needed at the receiving end based on the data type (float in the case of temp).

It doesn't sound like you have much experience with this, so, rather than assume what you do/don't know, it would probably be more efficient for you to ask very specific questions rather than us writing a bunch of detailed explanations that may either confuse or bore you until we get a better feel for what you need. In the meantime, I'll look for some examples of Pi and Windows Python code that does something like what you seem to be asking.
The best things in life aren't things ... but, a Pi comes pretty darned close! :D
"Education is not the filling of a pail, but the lighting of a fire." -- W.B. Yeats
In theory, theory & practice are the same - in practice, they aren't!!!

User avatar
croston
Posts: 703
Joined: Sat Nov 26, 2011 12:33 pm
Location: Blackpool
Contact: Website

Re: Control Raspberry Pi with another Program

Sun Feb 17, 2013 9:08 am

You might want to take a look at Remote Procedure Calls, such as XMLRPC. This is explained in the Raspberry Pi Educational Manual, page 118:
http://downloads.raspberrypi.org/Raspbe ... Manual.pdf

dspaedt
Posts: 28
Joined: Tue Jan 29, 2013 1:38 am

Re: Control Raspberry Pi with another Program

Mon Feb 18, 2013 12:26 am

Thank you both so much for the replies. The Ethernet socket explanation makes a lot of sense. I will begin googling how to have python and Microsoft Visual Basic send and wait for packets of data using Ethernet sockets.

This weekend I wrote about half of the VB program that will be the front end (HMI control) for the RPi.

Also, it's a lot easier for me to just write Python on my Windows machine using PyScripter as an IDE. Am I making the right assumption that if I do that and create a file called MyPythonProg.py, I can just put it in the memory of the Pi and it will run? Assuming of course it successfully runs on the Windows IDE.

Next step. Click a button on the windows program that sends "Temp = 72.4" over a standard Ethernet cable have the Python program running on the RPi see it and put it in a dictionary or something similar; {'temp' : '72.4'}. Then do it in reverse. If I can do that it should be easy street from there. :).

Any more help would be greatly appreciated.

User avatar
rpdom
Posts: 15568
Joined: Sun May 06, 2012 5:17 am
Location: Chelmsford, Essex, UK

Re: Control Raspberry Pi with another Program

Mon Feb 18, 2013 5:40 am

Just to check I understand what you are saying.

Are you planning to use the Pi as a controller to do the work, and the Windows program is just a simple interface between you and it?

Ok. That's pretty easily do-able, and sounds like an interesting project :)

If I were to do something like that (and I am considering it now) I'd probably run a webserver on the Pi, code up a simple CGI page or two and let the Pi do all the work. If you want to store stuff, put it in a database. Then you can acccess it from any computer on your home network that has a web browser. With a bit of Ajax you could even make the webpage update dynamically.

Just my thoughts, probably because I'm used to doing some things that way.

I'm not saying your method is wrong in any way - it isn't - it sounds fun :-)

Please keep us updated on your progress, and don't be afraid to ask questions.

I've done some socket programming for Linux in Perl and PHP. I use it to remotely manage some of my systems. There are a lot of bits of sample code out there that work well. I've never done anything that complex under Windows though :(

User avatar
rurwin
Forum Moderator
Forum Moderator
Posts: 4258
Joined: Mon Jan 09, 2012 3:16 pm
Contact: Website

Re: Control Raspberry Pi with another Program

Mon Feb 18, 2013 8:32 am

Sockets would work, but you'll have to handle all the exceptional cases and converting the values from ASCII into the right types. If you can find a XMLRPC library for VB.NET, then that is probably the easiest way. It all depends on what you want to learn about. Sockets are the basic objects that the whole Internet is built on. XMLRPC and such are the objects such things as the Facebook and Twitter APIs are based on... and Web pages and PHP are how the web works.

User avatar
socialdefect
Posts: 110
Joined: Mon Jun 25, 2012 9:02 pm
Location: Tilburg, the Netherlands
Contact: Website

Re: Control Raspberry Pi with another Program

Mon Feb 18, 2013 10:40 am

Another way of talking to your Pi over the network is using SSH. There is a Win build of OpenSSH. Using OpenSSH not only makes it easy to set-up an encrypted connection but it also saves you a lot of programming since you have direct access to the Linux shell and all installed commands.
In your controller app you just need to do a system call and execute something like this:

Code: Select all

ssh [email protected] command to execute
A big advantage of SSH is it's security features, eg; you can close all other firewall ports on the Pi and forward the ports you need trough a SSH tunnel. Also you can set-up an SSH authentication key for passwordless login. this way you can be sure your app is the only way one is able to connect.
== If it's not broke... I'm not done fixing it! ==

davej
Posts: 25
Joined: Mon Apr 16, 2012 2:49 pm

Re: Control Raspberry Pi with another Program

Mon Feb 18, 2013 11:10 am

rurwin wrote:Sockets would work, but you'll have to handle all the exceptional cases and converting the values from ASCII into the right types. ..... .
You may want to use OSC as the underlying protocol (one level up from sockets)since it will take care of the conversions for you and there are libraries for many popular languages. Also, the moment this grows to more than 2 machines or processes, OSC will win handsdown.

dspaedt
Posts: 28
Joined: Tue Jan 29, 2013 1:38 am

Re: Control Raspberry Pi with another Program

Mon Feb 18, 2013 6:20 pm

Well now I'm not sure. I googled the XMLRPC library for VB.NET and it looks just as complicated as using sockets?
This weekend I sucessfully coded a Server / Client in Visual Basic (I'll provide the code below).

I beilieve yes, you understand it right. The RPi will eventually do all the work. Mainly read temperature probes and fire relays. I'm a home brewer and
the ultimate goal is gain some control over my system. Build the RPi into an enclosure all wired up and ready to go. Walk up, plug in my brew system (which I
already do for other things, but eventually it will power the RPi as well), boot up my laptop, connect it to my enclosure, start my "control" program and essentially
it becomes my HMI, with buttons to Start Pump / Stop Pump, Heat Water to 175F, etc.

The plan is to fire:
2 Relays for burners
1 Relay for a pump
Monitor 3 Temperature Probes
And maybe a few more things.

I currently have two Server / Client Programs working and written in Visual Basic. They pass simple strings back and forth. I've only tried it on them on the same laptop
but I'll confirm that it works across two different machines (my Laptop and Desktop) in a few days. It seems best to make the RPi hold
the server Program and the laptop be the client program. So, now I have to figure out how in Python to make the RPi run as a server.

The two test programs I've made are listed below, if anyone knows Visual Basic .NET coding or is interested:

Just some code on the front Form to Start / Stop the Server.
Eventually will move the timers into the class and the rest of the logic won't be needed. The
server will run whenever the RPi is powered up.

Code: Select all

Public Class Form1
    Public ServerStopped As Boolean = False
    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        Timer1.Interval = 300
        Timer1.Enabled = False
        ServerStopped = False
        Button1.BackColor = Color.LimeGreen
        Button1.Text = "Started"
        ListenDelay()
    End Sub
    Private Sub ListenDelay()
        MyTCPListner.Main()
        If Not ServerStopped Then
            Timer1.Enabled = True
        Else
            Timer1.Enabled = False
        End If
    End Sub

    Private Sub Timer1_Tick(sender As Object, e As System.EventArgs) Handles Timer1.Tick
        Timer1.Enabled = False
        ListenDelay()
    End Sub
End Class
Server Class:

Code: Select all

Imports System
Imports System.IO
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Imports Microsoft.VisualBasic
Imports System.Threading
Public Class MyTCPListner
    Public Shared Sub Main()
        Dim server As TcpListener
        server = Nothing
        Try
            ' Set the TcpListener on port 13000. 
            Dim port As Int32 = 8585
            Dim localAddr As IPAddress = IPAddress.Parse("127.0.0.1")

            server = New TcpListener(localAddr, port)

            ' Start listening for client requests.
            server.Start()

            ' Buffer for reading data 
            Dim bytes(1024) As Byte
            Dim data As String = Nothing

            ' Enter the listening loop.
            While True
                Console.WriteLine("Looking for a Connection and can accept request from client")
                Thread.Sleep(100)
                If Not server.Pending() Then
                    Console.WriteLine("Done waiting for a connection... ")
                    server.Stop()
                    Exit While
                End If

                ' Perform a blocking call to accept requests. 
                ' You could also user server.AcceptSocket() here. 
                Dim client As TcpClient = server.AcceptTcpClient()
                Console.WriteLine("Connected!")

                data = Nothing

                ' Get a stream object for reading and writing 
                Dim stream As NetworkStream = client.GetStream()
                
                Dim i As Int32

                ' Loop to receive all the data sent by the client.
                i = stream.Read(bytes, 0, bytes.Length)
                'Need to troubleshoot this (If/End If) more but adding this finally got the thing TCP Listner to stop
                'by sending it a blank string
                If System.Text.Encoding.ASCII.GetString(bytes, 0, i) = "Stop Server" Then
                    'If Not stream.DataAvailable Then
                    stream.Close()
                    client.Close()
                    server.Stop()
                    Form1.ServerStopped = True
                    Form1.Button1.BackColor = Color.Red
                    Form1.Button1.Text = "Start Server"
                    Exit While
                End If
                While (i <> 0)
                    ' Translate data bytes to a ASCII string.
                    data = System.Text.Encoding.ASCII.GetString(bytes, 0, i)
                    Console.WriteLine("Received: {0}", data)

                    ' Process the data sent by the client.
                    data = data.ToUpper()
                    Dim msg As Byte() = System.Text.Encoding.ASCII.GetBytes(data)

                    ' Send back a response.
                    stream.Write(msg, 0, msg.Length)
                    Console.WriteLine("Sent: {0}", data)

                    i = stream.Read(bytes, 0, bytes.Length)

                End While
                ' Shutdown and end connection
                client.Close()
            End While
        Catch e As SocketException
            Console.WriteLine("SocketException: {0}", e)
        Finally
            server.Stop()
        End Try

        Console.WriteLine(ControlChars.Cr + "Will not accept communication....")
        Console.Read()
    End Sub 'Main

End Class
The Client Program. The button is just to test the sending of different messages.

Code: Select all

Public Class Form1
    Private dataReceived As Boolean = False
    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        Dim mess As String = TextBox1.Text
        If mess <> "" Then
            dataReceived = False
            Connect("localhost", mess)
        End If
    End Sub

    Private Sub Connect(server As [String], message As [String])
        Try
            ' Create a TcpClient. 
            ' Note, for this client to work you need to have a TcpServer  
            ' connected to the same address as specified by the server, port 
            ' combination. 
            Dim port As Int32 = 8585
            Dim client As New TcpClient(server, port)

            ' Translate the passed message into ASCII and store it as a Byte array. 
            Dim data As [Byte]() = System.Text.Encoding.ASCII.GetBytes(message)

            ' Get a client stream for reading and writing. 
            '  Stream stream = client.GetStream(); 
            Dim stream As NetworkStream = client.GetStream()

            ' Send the message to the connected TcpServer. 
            stream.Write(data, 0, data.Length)

            Console.WriteLine("Sent: {0}", message)

            ' Receive the TcpServer.response. 
            ' Buffer to store the response bytes.
            data = New [Byte](256) {}

            ' String to store the response ASCII representation. 
            Dim responseData As [String] = [String].Empty

            ' Read the first batch of the TcpServer response bytes. 
            Dim bytes As Int32 = stream.Read(data, 0, data.Length)
            responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes)
            Console.WriteLine("Received: {0}", responseData)
            dataReceived = True
            ' Close everything.
            stream.Close()
            client.Close()
        Catch e As ArgumentNullException

            Console.WriteLine("ArgumentNullException: {0}", e)
        Catch e As SocketException
            retry()
            'Console.WriteLine("SocketException: {0}", e)
        End Try

        Console.WriteLine(ControlChars.Cr + " Press Enter to continue...")
        Console.Read()
    End Sub 'Connect

    Sub retry()
        If dataReceived = False Then
            Button1.PerformClick()
        End If
    End Sub
End Class

davej
Posts: 25
Joined: Mon Apr 16, 2012 2:49 pm

Re: Control Raspberry Pi with another Program

Mon Feb 18, 2013 7:04 pm

dspaedt wrote:Well now I'm not sure. I googled the XMLRPC library for VB.NET and it looks just as complicated as using sockets?
This weekend I sucessfully coded a Server / Client in Visual Basic (I'll provide the code below).
Well, If you use OSC on the server side, the server essentially disappears, and the code you wrote condenses down to:
.
.
.
Initialise OSC lib
Associate pattern X (say /station1/pump1) with a callback that gets the action (on/off) as a parameter
Pattern Y (say /station1/temprequest) with another callback
.
.
rest of stuff specific to your particular app, ie monitoring temp etc
end up in wait loop

Because it is UDP you do not have to faff around with listen and connect etc, the system becomes async.

dspaedt
Posts: 28
Joined: Tue Jan 29, 2013 1:38 am

Re: Control Raspberry Pi with another Program

Mon Feb 18, 2013 7:23 pm

Thanks I'll look into this OSC UDP. You seem to know a bit about this.

What confuses me is this. Don't both programs have to act as Client and a Server?

I'd like the RPi to "push" data, like send the temps for example,every second or so and have the Laptop see these pushes.

And also, I'd like the Laptop to push data (like Start Pump for example) to the RPi and have the RPI see these pushes. Or no?

Essentially what I'm asking is, wether or not I use OSC or TCP sockets will each program have essentially to Functions (one to push data and one to listen for data)

Thanks.

dspaedt
Posts: 28
Joined: Tue Jan 29, 2013 1:38 am

Re: Control Raspberry Pi with another Program

Mon Feb 18, 2013 7:57 pm

I checked out OSC or at least what I think is OSC (Open Sound Control?)
It provides exactly what I was thinking originally. Send /Receive a basic data type; bool, integer, real, string.
However, it doesn't appear to have any means to incorporate into the two programming languages
I'm using and/or plan to use (Python and Visual Basic .NET).

I'm missing that, do you happen to have links to Python an VB.NET libraries. Also, some sample
code in those languages would really help.

davej
Posts: 25
Joined: Mon Apr 16, 2012 2:49 pm

Re: Control Raspberry Pi with another Program

Mon Feb 18, 2013 8:15 pm

dspaedt wrote:Thanks I'll look into this OSC UDP. You seem to know a bit about this.

What confuses me is this. Don't both programs have to act as Client and a Server?

I'd like the RPi to "push" data, like send the temps for example,every second or so and have the Laptop see these pushes.

And also, I'd like the Laptop to push data (like Start Pump for example) to the RPi and have the RPI see these pushes. Or no?

Essentially what I'm asking is, wether or not I use OSC or TCP sockets will each program have essentially to Functions (one to push data and one to listen for data)

Thanks.
The client / server issue is where OSC scores.

It is a broadcast protocol so any device/program can send data and any device/program can receive data.

All the programs agree about what UDP port number will be used
All the program initialise their own OSC library
Each program decides what patterns it will match (messages with unmatched patterns are essentially ignored (but you can use wildcards and partial URLs)) and what function to use for what match.

So, there are no client/server roles, it is all peer to peer.

There is no ACK part, ie you broadcast and forget, and on the receiving side you normally do not care where the message came from (except that the sender can make its name part of the payload)

So, on the Pi side (ie in the garage) if you get a temp request message, you just go and read the temp via the gpio, and then issue a broadcast message via OSC. Alternatively, the Pi just broadcasts the temp say once every 10 seconds. The Pi does not actually care that there is no device (the laptop) that is listening for the message.

Google for VB.NET OSC library and Python . There is also a standard library under linux called liblo (I think) and a lot of languages have glue files for it.

Dave

VK5FANG
Posts: 2
Joined: Mon Sep 25, 2017 9:46 pm

Re: Control Raspberry Pi with another Program

Sat Oct 21, 2017 9:27 pm

Hi,
I'm replying to this old post as this method has been overlooked and may help someone, somewhere, sometime.

I needed to do this years ago, and found the simple and easy cross platform method was for the machine gathering the sensor data to do so into a dynamic array. When appropriate, write the contents of the array to a comma delimited file on a shared drive, adjusting it's array minus the written data.

The receiving machine simply picks up the data from that drive and then optionally deletes the line of read data, or writes an "ack" flag if you prefer.

Worked for me without flaw, without data loss when networks/computers were not reliable. Even had a third "audit" computer quietly copying the file as backup, and causing an alert if the data gatherer stopped writing to the shared file/drive.

Maybe a similar method adjusted to your needs would suit you. When a novice, We were taught always to "keep it simple".

User avatar
jadro
Posts: 429
Joined: Sun Oct 02, 2016 1:20 pm
Location: Croatia

Re: Control Raspberry Pi with another Program

Mon Oct 23, 2017 10:16 am

My answer now and ever will be MQTT. CloudMqtt.com as online MQTT server and windows MQTT VB or C# client on computer, Android MQTT application (Whatever which one) and Raspberry Pi Python MQTT Client... Works together
Oracle backend database developer
SmartHome IoT & Microprocessor enthusiast and hobbyist

Sir FICO
Posts: 31
Joined: Sat Nov 07, 2015 11:34 pm

Re: Control Raspberry Pi with another Program

Mon Oct 23, 2017 11:57 pm

Just to second the use of MQTT. Someone on here suggested it to me some time back and when I asked about program to program communication and I was pondering using the file system. When I looked into it I found it relatively trivial to get it to work on RPi's and my mac computer etc. for program to program communications running on different computers. My MQTT broker runs on a RPi 2 and the messages are received and sent (subscribed and published :) ) awesomely quick. When my mac publishes 'glighton' via a program button click, the ZeroW pi that receives its message via a wireless router, and the router is on the end of an ethernet cable some 60 metres from the house, the light controlled by the ZeroW lights up instantly.

User avatar
jadro
Posts: 429
Joined: Sun Oct 02, 2016 1:20 pm
Location: Croatia

Re: Control Raspberry Pi with another Program

Tue Oct 24, 2017 6:26 am

At first I was afraid how to connect Raspberry Pi within MQTT mosquitto broker and all stuff that are used with MQTT. I read many web pages that all on this forum suggest to me and at first I was confused but when I go to install all this stuff, I realized that MQTT is simple and light and fast. Ok, there is always some points that I do not understaind, but here on this forum are many great people who give us support...
Oracle backend database developer
SmartHome IoT & Microprocessor enthusiast and hobbyist

Return to “General discussion”