|
Post by quinton on May 29, 2014 12:24:38 GMT -8
Hi, I'm also new to programming and I like the the app as it suits my project perfectly but I can't marry the two together. I have a python program which uses a PIR motion sensor, servo motors and an OLED display to output motion detection and when buttons are pushed. I read one of the post from another user on which you guys replied to use the example. I managed to assign a button to call my program to run and it works fine but what I can't understand is how to I assign an LED on the app to turn on when motion is detected or to program 3 buttons to run the a the servo motor. All this info is displayed on my OLED display but I would like it to also show up on the app as well as control the program from the app.
Can an you please give me a step by step guide line to assign each device *button to operate servo motor x2 *LED to display when motion is detected *And in future Ultrasonic to work with the bar meter to sense distance like a car reverse sensor.
Again I'm new to programming but I'm eager to learn more. Pleeeeeease Help me, I haven't slept for days trying to make it work...
|
|
|
Post by SDL on Jun 3, 2014 10:08:52 GMT -8
Hi quinton! I've been gone on vacation for the past five days. Sorry it took me so long to get back to you. Here's how you (with the current app - there will be more LIVE options later in the summer) can update an LED. First of all, check out ProjectCuracao (www.switchdoc.com) and the code posted on github.com/projectcuracao. Faraday/John has done everything you are asking about and has posted all of this source code. The LEDs are pretty simple. Set the page to refresh periodically and have RasPiConnectServer poll your program (through a file or a function) and set the LED accordingly. For starting motors and such, you need to pass information from the RasPiConnect Server to your running program. Here is how it is done in MouseAir (another program by Faraday - he hasn't posted the code yet, but he will shortly. Again check his blog periodically (www.switchdoc.com). He writes commands from RasPiConnectServer to a command file and then has his MouseAir Program periodically check the file. In ProjectCuracao, he did it differently. Quoting from an email from him, he says: "First of all, I have an new article coming out next month in MagPi magazine that talks about a lot of these issues and how I solved them in MouseAir. in Project Curacao, I used command functions in my ProjectCuracao.py files to move a camera shutter (using a servo motor) by calling the function from a library. Take a look at the Open Shutter button in Local.py on github.com/ProjectCuracao.
In MouseAir, I used a command file to move information from RasPiConnectServer to MouseAir.py. MouseAir.py periodically reads the command file. The code in Local.py looks like this:
The below comes from the soon to be published article in MagPi Magazine.
On the MouseAir side, the software for receiveing commands from RasPiConnect is contained in processcommand.
def processCommand():
f = open("/home/pi/MouseAir/state/MouseCommand.txt", "r") command = f.read() f.close()
if (command == "") or (command == "DONE"): # Nothing to do return False
# Check for our commands pclogging.log(pclogging.INFO, __name__, "Command %s Recieved" % command)
print "Processing Command: ", command if (command == "FIREMOUSE"): fireMouse() completeCommand() return True
if (command == "TAKEPICTURE"): utils.threadTakePicture("Picture Taken -RasPiConnect Command") completeCommand() return True ...
def completeCommand():
f = open("/home/pi/MouseAir/state/MouseCommand.txt", "w") f.write("DONE") f.close()
The MouseCommand.txt file is first written by the RasPiConnectServer program and then read by MouseAir. When the command is complete, MouseAIr writes "DONE" into the command file, telling RasPiConnectServer that it is finished and ready for the next command. Note that the RasPiConnect app keeps all commands in a queue and will not send another command until either a timeout occurs (programmable) or it gets a response from the Raspberry Pi.
The RasPiConnectServer Software RasPiConnectServer is a python program provided for connection from a Raspberry Pi to the RasPiConnect app. The file that you have to change (in addition to the config.py file) to connect to the MouseAir software is called Local.py. MiloCreek provides full documentation for Local.py and the rest of the server at www.milocreek.com under the documentation link. Each button is pretty simple to do.
There are some other setup items such as setting URLs for your Raspberry Pi that are fully explained in the manual.
All of the software that you need to write is placed in a file called Local.py. There is an example Local.py file provided in the server download. To illustrate how to write the interface, I will follow one entire button through the process.
I will use the Motors On button as an example. The Motors On button controls the DC motors that shoot the mouse up in the air. It has two states, "On" and "Off". This makes it a perfect candidate for a Feedback Action Button.
When you add a control in RasPiConnect, you can set the control code (usually a unique identifier) for the button. By convention, each Feedback Action Button starts with "FB". I assigned our motor control button a control code of "FB-16".
When you hit the button on RasPiConnect an XML message (or optionally a JSON or raw mode message) is sent from the iPad to the RaspberryPi. The message is parsed by the RasPiConnectServer software and the results are presented to your customized code in the Local.py file. You don't have to deal with any of the parsing or handshaking. The libraries do all of this for us. The button is then presented to Local.py. We wrote one small routine to interface to the MouseAir.py command file.inse def sendCommandToMouseAirAndWait(command):
The next section is the "money code", that is, the code where the functionality of the button is implemented. # object Type match if (objectType == FEEDBACK_ACTION_BUTTON_UITYPE):
if (Config.debug()): print "FEEDBACK_ACTION_BUTTON_UTYPE of %s found" % objectServerID
# FB-16 - turn motors on if (objectServerID == "FB-16"): #check for validate request # validate allows RasPiConnect to verify this object is here if (validate == "YES"): outgoingXMLData += Validate.buildValidateResponse("YES") outgoingXMLData += BuildResponse.buildFooter() return outgoingXMLData
# not validate request, so execute responseData = "XXX" if (objectName is None): objectName = "XXX" lowername = objectName.lower() if (lowername == "motors on"):
print "set Motors On"
We now send the command to MouseAir.
status = sendCommandToMouseAirAndWait("MOTORSON") responseData = "motors Off" responseData = responseData.title()
Note we have now "toggled" the button by sending "Motors Off" back to the app to set up the button for the next push.
elif (lowername == "motors off"):
status = sendCommandToMouseAirAndWait("MOTORSOFF") responseData = "Motors On" responseData = responseData.title()
The default section is in case of a time out and the button becomes blank. In that case, we want the motors off.
# defaults to Motors off else: print "Motors Off" status = sendCommandToMouseAirAndWait("MOTORSOFF") lowername = "Motors On" responseData = lowername.title()
The default section is in case of a time out and the button becomes blank. In that case, we want the motors off.
# defaults to Motors off else: print "Motors Off" status = sendCommandToMouseAirAndWait("MOTORSOFF") lowername = "Motors On" responseData = lowername.title() FInally, the rest of the XML response is built. By the way, if you somehow screw up the XML, RasPiConnect just rejects it. There is error checking built into the App as well as checksum on each response. outgoingXMLData += BuildResponse.buildResponse(responseData) outgoingXMLData += BuildResponse.buildFooter() return outgoingXMLData Looking at the code, you can see the command that is written to the MouseAir command file. The software then waits for the "DONE" and then sends the response (which is the text used for the button on the iPad. If you sent a "Motor On" command, the response to be sent back would be "Motor Off" and then the "Motor Off" would be displayed on the button on the app.
That is the complete cycle. This design pattern is used for all of the controls."Thanks for the answer Faraday! Best regards, BP
|
|
|
Post by quinton on Jun 4, 2014 9:06:57 GMT -8
Hi BP
Hope i find you well and that you enjoyed your vacation. Thank you so much for your reply and info, I'm gonna put my geeky glasses and my thinking cap on and get right to it and i'll let you know soon how i get on.
Thanks again BP
Quinton.
|
|
|
Post by quinton on Jun 10, 2014 12:04:31 GMT -8
ok now, I've looked and the files according to your recommendation (ProjectCuracao) and i have tried them but none of them seem to work and i can't get round were i'm going sideways. I have tried the FeedBack button example numerous times but i keep getting errors and invalid codes. Is there a basic FeedBack button code that i can use that is easier to understand for beginners such as your Button Example.py that comes with the Local folder. I find things work better when i use that program as a templet. Another thing i don't get is when you say "The LEDs are pretty simple. Set the page to refresh periodically and have RasPiConnectServer poll your program (through a file or a function) and set the LED accordingly." ( ) Have you got a step by step example to explain your statement above and how to : when you press a button the LED turns "on" to your preferred colour when the XML output text is "OK"
|
|
|
Post by SDL on Jun 11, 2014 13:04:33 GMT -8
Quinton,
Here is a simple Local.py to get you going. Put this in your Local.py file and run the server with Debug turned on (see the manual).
It blinks an LED on GPIO 7.
ProjectCuracao and MouseAir are pretty complex applications as you found out. We are including this in the new RasPiConnectServer Release.
Best regards,
#!/usr/bin/python # Filename: local.py # MiloCreek BP MiloCreek # Version 3.0 6/11/2014 # # Local Execute Objects for RasPiConnect # to add Execute objects, modify this file # # #
# system imports import sys import subprocess import os import time # RasPiConnectImports
import Config import Validate import BuildResponse
import RPi.GPIO as GPIO ## Import GPIO library GPIO.setmode(GPIO.BOARD) ## Use board pin numbering GPIO.setup(7, GPIO.OUT) ## Setup GPIO Pin 7 to OUT
# To put an LED on GPIO Pin 7 on your pi read this: # http://www.thirdeyevis.com/pi-page-2.php #
def ExecuteUserObjects(objectType, element):
# Example Objects
# fetch information from XML for use in user elements
#objectServerID is the RasPiConnect ID from the RasPiConnect App
objectServerID = element.find("./OBJECTSERVERID").text objectID = element.find("./OBJECTID").text
if (Config.debug()): print("objectServerID = %s" % objectServerID) # # check to see if this is a Validate request # validate = Validate.checkForValidate(element)
if (Config.debug()): print "VALIDATE=%s" % validate
# Build the header for the response
outgoingXMLData = BuildResponse.buildHeader(element)
# # B-1 Flashes LED on GPIO if (objectServerID == "B-1"):
#check for validate request # validate allows RasPiConnect to verify this object is here
if (validate == "YES"): outgoingXMLData += Validate.buildValidateResponse("YES") outgoingXMLData += BuildResponse.buildFooter() return outgoingXMLData
# not validate request, so execute #
# # # Execute your code # #
# To put an LED on GPIO Pin 7 on your pi read this: # http://www.thirdeyevis.com/pi-page-2.php # if (Config.debug()): print("Button # %s: Blinking GPIO pin 7" % objectServerID)
GPIO.output(7,True) ## Turn on GPIO pin 7 time.sleep(1) ## sleep 1 second GPIO.output(7,False) ## Turn off GPIO pin 7 responseData = "OK" ## send an OK back to the App
print "responseData =", responseData
# # # Done with your code # #
outgoingXMLData += BuildResponse.buildResponse(responseData) outgoingXMLData += BuildResponse.buildFooter() return outgoingXMLData
else: # returning a zero length string tells the server that you have not matched # the object and server return ""
|
|
|
Post by quinton on Jun 12, 2014 6:04:22 GMT -8
Thanks for the above code which indeed will be come useful, how ever perhaps I didn't make it clear what I meant in my previous post. The BUTTONS and LEDs are which on the app to work together. Such that for example: (on the App) I have programmed two buttons one will open a door and One will close a door. Each button has been assigned on the App to call/run a program in the Local.py program If the button is pressed to open I would like an LED on the App to light up as GREEN If the button is pressed to close I would like the same LED on the app to light up as RED if a motion is detected on a PIR sensor I would like another LED to turn on (On the App)
Hope this gives a better picture of what help I need. Thanks again BP
Quinton.
|
|
|
Post by SDL on Jun 12, 2014 19:00:13 GMT -8
Quinton,
You need to write code that "opens a door" and then execute that code when you receive a button refresh like in the example above. I think you understand that.
What you do for the button / LED combination is:
1) Set up the LED on RasPiConnect to refresh when you hit a button.
2) when the button is executed, in that code write out a variable to a file indicating that the button has been pushed (say, a text string "GREEN")
3) In your refresh code for the LED control, read that file in and if it says "GREEN", set the color the LED to the number corresponding to GREEN (look in the control documentation)
4) You alternate states with each button pushed (write "RED" for example if the file contains "GREEN") will be written to the file.
5) With regards to your PIR sensor, when it is triggered (say in another program or thread), write to a file what happened
6) The LED in this case, when refreshed, would read from the PIR file and set the color appropriately.
All you need to do in general, is communicate information to the server and then read that information and send it back to RasPiConnect.
Best regards,
BP
|
|