Arduino Communications
(90 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
− | < | + | <anyweb>http://combustory.com/wiki/ads/ad_rtc.html</anyweb> |
+ | {{default}} | ||
+ | |||
+ | <anyweb>http://combustory.com/wiki/ads/ad_rtc_1.html</anyweb> | ||
== Summary == | == Summary == | ||
− | In my search for | + | In my search for methods to communicate with the Arduino board, I found lots of ways that required me to learn new languages or learn serial communication programming. I do want to eventually pick up these skills, but I found a quicker way for my needs. I have learned over time that you can always find a better way to solve a problem, but I realize that the amount of time to learn that better way is sometimes greater than the project time-frame, and therefore just solve it in the best way you can with the tools you have. I believe that the solution below encompasses that spirit. Here you will find a quick, dirty yet effective solution for communicating with the Arduino. |
This solution met my goals, but it may not meet yours. It is limited in the effect that a transfer in a message may take as long as 5 sec. This fits fine for my needs where I am just looking to form a distributed network of smart sensors/controllers that allow the setting of certain variables and the reporting of alarms and/or useful tracking information from the individual controllers. | This solution met my goals, but it may not meet yours. It is limited in the effect that a transfer in a message may take as long as 5 sec. This fits fine for my needs where I am just looking to form a distributed network of smart sensors/controllers that allow the setting of certain variables and the reporting of alarms and/or useful tracking information from the individual controllers. | ||
Line 9: | Line 12: | ||
'''Note: I owe a BIG debt of gratitude to all the Arduino hackers that provided me with the tools/code/knowledge to allow this solution''' | '''Note: I owe a BIG debt of gratitude to all the Arduino hackers that provided me with the tools/code/knowledge to allow this solution''' | ||
− | == Functional Description of Method == | + | == Functional Description of the Method == |
+ | |||
+ | This method creates a log file that is created by an Arduino board using serial communications that is sent to a terminal which is redirected to a file. The file can then be used by any software you desire to process the messages from the Arduino board. To send messages to the Arduino board the use of Arduino-Serial (a command line utility) is placed in a BASH script that is used to constantly poll for the existence of a ''command'' file. When a ''command'' file is found, the BASH script will send the commands in the file to the Arduino board. The response by the Arduino is to follow the command input and print response data out to the terminal, which is sent to the log file. | ||
+ | |||
+ | If your brain just got scrambled, join the club. There were several technical hurdles I was concerned about as soon as I thought of this method. I did not even think this would work at first, but it turns out to function just fine. (Until Further Notice! `,~) | ||
+ | |||
− | + | In this diagram you will find the basic idea behind the method. This diagram is based on the example I provide below. | |
− | + | [[Image:Arduino_Com_diagram.jpg | 400px]] | |
== Requirements == | == Requirements == | ||
Line 23: | Line 31: | ||
* Your favorite development language | * Your favorite development language | ||
* Basic Linux operational skill | * Basic Linux operational skill | ||
− | * Knowledge of ''samba'' or '' | + | * Knowledge of ''samba'' or ''NFS'' if networking is desired |
Line 34: | Line 42: | ||
* Development languages - BASH scripting for Linux and AutoIT for windows | * Development languages - BASH scripting for Linux and AutoIT for windows | ||
* Knowledge of ''samba'' for sharing folders over the network | * Knowledge of ''samba'' for sharing folders over the network | ||
− | |||
− | |||
== Example of Method == | == Example of Method == | ||
Line 67: | Line 73: | ||
'''Buy an Arduino Board - ''' There are lots of options to buy a board. I chose the standard USB version from the guidance of this [http://www.arduino.cc/en/Main/Buy Arduino link]. If you follow this [http://www.freeduino.org/buy.html Freeduino link] you will find many options including my favorite the Bare Bones Board from [http://moderndevice.com/ moderndevice.com] and [http://wulfden.org/freeduino/freeduino.shtml wulfden.com]. Check out the [http://www.moderndevice.com/RBBB_revB.shtml RBBB assembly]. These options are super cheap and I will definitely be buying my next Arduino based board from these sites. These folks have knocked down the price of micro-controller development boards. | '''Buy an Arduino Board - ''' There are lots of options to buy a board. I chose the standard USB version from the guidance of this [http://www.arduino.cc/en/Main/Buy Arduino link]. If you follow this [http://www.freeduino.org/buy.html Freeduino link] you will find many options including my favorite the Bare Bones Board from [http://moderndevice.com/ moderndevice.com] and [http://wulfden.org/freeduino/freeduino.shtml wulfden.com]. Check out the [http://www.moderndevice.com/RBBB_revB.shtml RBBB assembly]. These options are super cheap and I will definitely be buying my next Arduino based board from these sites. These folks have knocked down the price of micro-controller development boards. | ||
==== Step 2 ==== | ==== Step 2 ==== | ||
− | '''Load the Arduino software on your linux box - ''' Here are the [http://www.arduino.cc/playground/Learning/Linux Linux Instructions]. For my Arduino, I used Ubuntu 8.x. I also recommend you do a google search of | + | '''Load the Arduino software on your linux box - ''' Here are the [http://www.arduino.cc/playground/Learning/Linux Linux Instructions]. For my Arduino, I used Ubuntu 8.x. I also recommend you do a google search of Arduino and your linux type to find any type of specific hiccups that inevitably find there way into installs. The Ubuntu instuctions I ended up using was from [http://principialabs.com/running-arduino-on-ubuntu/ principialabs.com] and after all was said and done these instructions worked without a single problem for me. |
+ | |||
==== Step 3 ==== | ==== Step 3 ==== | ||
''' Load the sample Arduino code into your Arduino board - ''' Here is the code I used. I will not claim it to be pretty, but it does work as a test for this method. Most likely you will have to modify some of the numbers around the input. I will give you my schematic, but I am sure that your set up will vary somewhat and that will change the Threshold and Voltage reading numbers. | ''' Load the sample Arduino code into your Arduino board - ''' Here is the code I used. I will not claim it to be pretty, but it does work as a test for this method. Most likely you will have to modify some of the numbers around the input. I will give you my schematic, but I am sure that your set up will vary somewhat and that will change the Threshold and Voltage reading numbers. | ||
+ | <source lang="c"> | ||
/* | /* | ||
* AnalogInput with Thermistor | * AnalogInput with Thermistor | ||
Line 154: | Line 162: | ||
} | } | ||
//*****************************************************The End*********************** | //*****************************************************The End*********************** | ||
+ | </source> | ||
==== Step 4 ==== | ==== Step 4 ==== | ||
− | ''' Create a Folder on the Linux box and share the Folder over the network using ''samba'' - ''' There is not much to say here other than learn your ''samba'' and make it happen. There are | + | ''' Create a Folder on the Linux box and share the Folder over the network using ''samba'' - ''' There is not much to say here other than learn your ''samba'' and make it happen. There are literally tons of info on this subject on the web. Other than that make sure that the permissions are set on the shared folder to allow creating and writing files. |
+ | |||
==== Step 5 ==== | ==== Step 5 ==== | ||
− | ''' Compile the Arduino-Serial software and place the executable in the shared folder from Step 4 - ''' This step gave me a little bit of an issue. I had to comment out a few baud speed lines. It was not | + | ''' Compile the Arduino-Serial software and place the executable in the shared folder from Step 4 - ''' This step gave me a little bit of an issue. I had to comment out a few baud speed lines. It was not that difficult to figure out, because the compiler gave pretty clear error messages and these [http://todbot.com/blog/2006/12/06/arduino-serial-c-code-to-talk-to-arduino/ Arduino-Serial] instructions even mentioned this as an issue and even though it is mentioned and supposedly fixed, there is still one more line he did not comment out. Make sure any line that looks like this: |
case 28800: brate=B28800; break; | case 28800: brate=B28800; break; | ||
Line 166: | Line 176: | ||
==== Step 6 ==== | ==== Step 6 ==== | ||
− | ''' Load the sample BASH scripting text into an executable file in your shared folder from Step 4 on the Linux box - ''' Here is the BASH script. It is a script that goes into an infinite loop and constantly polls for two files, a ''command'' file and a ''clear_log'' file. When it sees those files it takes action to either send commands or clear the log file. The files are sent from some other application that are used to control the communication to the Arduino. In this example I use AutoIT as the controlling software (See Step 9). | + | ''' Load the sample BASH scripting text into an executable file in your shared folder from Step 4 on the Linux box - ''' Here is the BASH script. It is a script that goes into an infinite loop and constantly polls for two files, a ''command'' file and a ''clear_log'' file. When it sees those files it takes action to either send commands or clear the log file. The files are sent from some other application that are used to control the communication to the Arduino. In this example I use AutoIT as the controlling software (See Step 9). I will leave it to the reader to decode these commands. |
− | + | <source lang="bash"> | |
#!/bin/bash | #!/bin/bash | ||
# File name CommandPoll | # File name CommandPoll | ||
Line 189: | Line 199: | ||
rm command # remove the command file | rm command # remove the command file | ||
fi | fi | ||
− | if [ -f clear_log ] # | + | if [ -f clear_log ] # Does the clear_log file exist |
then | then | ||
echo > arduino_log | echo > arduino_log | ||
rm clear_log | rm clear_log | ||
+ | fi | ||
+ | if [ -f exit_poll ] # Does the exit_poll file exist | ||
+ | then | ||
+ | # Kill any tail commands logging the terminal | ||
+ | exec ps ax | grep "tail -f /dev/ttyUSB0" | grep ? | awk '{system("kill " $1)}' | ||
+ | rm exit_poll | ||
+ | exit 0 # Exit CommandPoll script | ||
fi | fi | ||
sleep 1 # Sleep for one second or your processor will run 100% (optional) | sleep 1 # Sleep for one second or your processor will run 100% (optional) | ||
done | done | ||
− | exit 0 | + | exit 0 |
+ | </source> | ||
==== Step 7 ==== | ==== Step 7 ==== | ||
− | ''' Build your Thermistor | + | ''' Build your Thermistor and LED circuits based on the diagrams or something similar - ''' That's it, just follow the diagrams or create a comparable solution. |
+ | |||
+ | |||
+ | |||
+ | [[Image:arduino_com_circuit.jpg]] | ||
+ | |||
==== Step 8 ==== | ==== Step 8 ==== | ||
− | ''' Map your ''samba'' shared folder | + | ''' Map your ''samba'' linux shared folder to a windows drive - ''' For this example you have to map a drive on your windows box. I think I will leave the details on how to accomplish this task to a google search on mapping drives in windows. It is fairly straight forward. I mapped my drive to P: for no particular reason, but what ever you map it to, you will be able to select the drive from within the AutoIT GUI. |
+ | |||
==== Step 9 ==== | ==== Step 9 ==== | ||
''' Load AutoIT on your windows box - ''' Go to the [http://www.autoitscript.com/autoit3/ AutoIT] site and load this very powerful and free software. This software has been around for a while and it has a fairly active development crew, which creates constant improvements, extensions and user libraries. It is a very powerful GUI scripting tool and it is very easy to create a GUI application as well. I have created many great utilities using this software. It is not for super powerful software needs, but with today's computers, it does quite a bit. LOVE this tool. | ''' Load AutoIT on your windows box - ''' Go to the [http://www.autoitscript.com/autoit3/ AutoIT] site and load this very powerful and free software. This software has been around for a while and it has a fairly active development crew, which creates constant improvements, extensions and user libraries. It is a very powerful GUI scripting tool and it is very easy to create a GUI application as well. I have created many great utilities using this software. It is not for super powerful software needs, but with today's computers, it does quite a bit. LOVE this tool. | ||
+ | ==== Step 10 ==== | ||
+ | ''' Use the sample AutoIT script to test the solution - ''' This code is a utility that will allow you to select the mapped shared windows drive/path and a working directory. There is a drop down menu with four commands that that will make the Arduino respond. This program will create a ''command'' file, fill it with the command string and place it in the Network Dir. The Software will wait 5 seconds and then retrieve the results and place it in the text window. Then the program will place the ''clear_log'' file in the Network Dir. I will not cover the use of this software here, refer to the User Guide section. For now just get this loaded into AutoIT and hit F5 to get it to run. You can run AutoIT programs interpreted or compiled. Pressing F5 runs it as interpreted. | ||
+ | <source lang="autoit"> | ||
+ | ; Arduino Communications and Control | ||
+ | ; File name: Arduino_Com_v.02.au3 | ||
+ | ; 31 Jul 2008 - John Vaughters <http://www.combustory.com> | ||
+ | ; This is a Utility to Communicate with the Arduino Control board | ||
+ | #include <WindowsConstants.au3> ; added to resolve issue with AutoIT v 3.3 | ||
+ | #include <GuiConstants.au3> | ||
+ | #include <GuiEdit.au3> | ||
+ | #include <file.au3> | ||
+ | #include <Date.au3> | ||
+ | #include <IE.au3> | ||
+ | |||
+ | ;************* | ||
+ | ; _Load_Results() loads the temp file into the desired control then deletes the temp file | ||
+ | ; $w_dir is the working directory where the file exists | ||
+ | ; $ctl_to_load is the place to load the file contents | ||
+ | ; $temp_file is the temporary file to load the data from | ||
+ | ; The function returns the number of lines loaded from the file | ||
+ | |||
+ | Func _Load_Results ($w_dir, $ctl_load_to, $temp_file) | ||
+ | Dim $aRecords | ||
+ | If Not _FileReadToArray($w_dir & $temp_file,$aRecords) Then | ||
+ | MsgBox(4096,"Error", " Error reading log to Array error:" & @error) | ||
+ | Exit | ||
+ | EndIf | ||
+ | |||
+ | For $x = 1 to $aRecords[0] | ||
+ | if StringLen($aRecords[$x]) > 0 then GuiCtrlSetData($ctl_load_to, $aRecords[$x] & @CRLF, 1) | ||
+ | Next | ||
+ | ;Delete the temporary file | ||
+ | RunWait(@ComSpec & " /c " & "del " & $temp_file, $w_dir & "",@SW_HIDE) | ||
+ | Return ($aRecords[0]-1) | ||
+ | EndFunc | ||
+ | |||
+ | ;Initialize Variable Defaults | ||
+ | $working_dir = @DesktopDir & "\" | ||
+ | $working_file = "arduino_log" | ||
+ | $poll_delay = 5000 ; This is the delay the program waits before collecting the command results | ||
+ | $network_dir = "P:\" ; Default network directory | ||
+ | $process_results = False ;Processing Flag | ||
+ | $command_get_begin = TimerInit() ;Initialize Timer | ||
+ | ; GUI | ||
+ | GuiCreate(" Arduino Communications and Control", 700, 600) | ||
+ | |||
+ | ; MENU | ||
+ | $filemenu = GuiCtrlCreateMenu("&File") | ||
+ | $fileitem = GUICtrlCreateMenuitem ("Open",$filemenu) | ||
+ | GUICtrlSetState(-1,$GUI_DEFBUTTON) | ||
+ | $exititem = GUICtrlCreateMenuitem ("Exit",$filemenu) | ||
+ | $helpmenu = GuiCtrlCreateMenu("Help") | ||
+ | $infoitem = GUICtrlCreateMenuitem ("Info",$helpmenu) | ||
+ | |||
+ | |||
+ | ; LOGO PIC | ||
+ | GuiCtrlCreatePic("logo.jpg",0,0, 100,140) | ||
+ | |||
+ | ; AVI for letting the user know the system is processing | ||
+ | $processing = GuiCtrlCreateAvi("sampleAVI.avi",0, 405, 140, 32, 32) | ||
+ | |||
+ | ; Tabbed Result Window | ||
+ | $tab_result_start_x = 20 | ||
+ | $tab_result_start_y = 175 | ||
+ | $tab_result_size_x = 650 | ||
+ | $tab_result_size_y = 400 | ||
+ | $tab_result_title_2 = "Command Results" | ||
+ | $tab_result_title_4 = "Sys Info" | ||
+ | GuiCtrlCreateTab($tab_result_start_x, $tab_result_start_y, $tab_result_size_x , $tab_result_size_y) | ||
+ | GuiCtrlCreateTabItem($tab_result_title_2) | ||
+ | $edit_ctl_tab2 = GuiCtrlCreateEdit(@CRLF & "", $tab_result_start_x + 10 , $tab_result_start_y + 40, $tab_result_size_x - 20, $tab_result_size_y - 50) | ||
+ | GuiCtrlCreateTabItem($tab_result_title_4) | ||
+ | $edit_ctl_tab4 = GuiCtrlCreateEdit(@CRLF & "", $tab_result_start_x + 10 , $tab_result_start_y + 40, $tab_result_size_x - 20, $tab_result_size_y - 50) | ||
+ | GuiCtrlCreateTabItem("") | ||
+ | |||
+ | ; Combo Arduino Command File Type | ||
+ | $combo_ctl_search_file = GuiCtrlCreatecombo("*", 240, 145, 120, 100) | ||
+ | GUICtrlSetData(-1,"C5|D5|T1|","C5") ; add other item snd set a new default | ||
+ | GuiCtrlCreateLabel("Arduino Command", 245, 170, 150, 20) | ||
+ | |||
+ | ; Current Working Directory Label | ||
+ | $combo_ctl_working_dir = GuiCtrlCreateLabel($working_dir, 240, 80, 450, 22,$WS_DLGFRAME) | ||
+ | GUICtrlSetBkColor(-1,0xffffff) | ||
+ | GuiCtrlCreateLabel("Working Directory", 245, 105, 200, 20) | ||
+ | |||
+ | ; Current Network Directory Label | ||
+ | $combo_ctl_network_dir = GuiCtrlCreateLabel($network_dir, 240, 20, 450, 22,$WS_DLGFRAME) | ||
+ | GUICtrlSetBkColor(-1,0xffffff) | ||
+ | GuiCtrlCreateLabel("Network Directory", 245, 45, 200, 20) | ||
+ | |||
+ | ; BUTTON | ||
+ | $search_btn = GuiCtrlCreateButton("Go", 370, 143, 25, 25) | ||
+ | $file_btn = GuiCtrlCreateButton("Working Dir", 125, 77, 100, 25) | ||
+ | $network_btn = GuiCtrlCreateButton("Network Dir", 125, 18, 100, 25) | ||
+ | $site_btn = GuiCtrlCreateButton("www.combustory.com", 0, 145, 135, 22) | ||
+ | $clear_btn = GuiCtrlCreateButton("Clear", 620, 170, 50, 22) | ||
+ | |||
+ | ; List System Info | ||
+ | GuiCtrlSetData($edit_ctl_tab4, "Computer: " & @CRLF & _ | ||
+ | "----------------------------------------------------------" & @CRLF & _ | ||
+ | "IP Address: " & @IPAddress1 & @CRLF & _ | ||
+ | "Computer Name: " & @ComputerName & @CRLF & _ | ||
+ | "OS: " & @OSVersion & @CRLF & _ | ||
+ | "Sys Dir: " & @SystemDir & @CRLF & @CRLF) | ||
+ | ; GUI MESSAGE LOOP | ||
+ | GuiSetState() | ||
+ | |||
+ | ; Main Event Loop | ||
+ | While 1 | ||
+ | ; After every loop check if the user clicked something in the GUI window | ||
+ | $msg = GUIGetMsg() | ||
+ | if $process_results = True Then | ||
+ | if $poll_delay < TimerDiff($command_get_begin) Then | ||
+ | RunWait(@ComSpec & " /c " & "type arduino_log>results.txt", $network_dir,@SW_HIDE) | ||
+ | ; Load command results into Command Results tab | ||
+ | GuiCtrlSetData($edit_ctl_tab2, "------------------------------------------------------------------" & @CRLF,1) | ||
+ | GuiCtrlSetData($edit_ctl_tab2, "Command: " & GUICtrlRead($combo_ctl_search_file) & @CRLF,1) | ||
+ | GuiCtrlSetData($edit_ctl_tab2, "Results: " & @CRLF,1) | ||
+ | _Load_Results ($network_dir, $edit_ctl_tab2, "results.txt") | ||
+ | GuiCtrlSetData($edit_ctl_tab2, "******************************************************************" & @CRLF,1) | ||
+ | $process_results = False | ||
+ | RunWait(@ComSpec & " /c " & "echo>clear_log", $network_dir,@SW_HIDE) ; Send message to Linux polling script to clear the log | ||
+ | GUICtrlSetState ($processing, 0) | ||
+ | EndIf | ||
+ | EndIf | ||
+ | Select | ||
+ | |||
+ | ; Check if user clicked on the close button | ||
+ | Case $msg = $GUI_EVENT_CLOSE Or $msg = $exititem | ||
+ | ; Destroy the GUI including the controls | ||
+ | GUIDelete() | ||
+ | ; Exit the script | ||
+ | Exit | ||
+ | |||
+ | ; Check if user clicked on the File Open button | ||
+ | Case $msg = $fileitem | ||
+ | $working_dir = FileSelectFolder("Choose Folder...","",4,"") & "\" | ||
+ | GuiCtrlSetData($combo_ctl_working_dir, $working_dir) | ||
+ | |||
+ | ; Check if user clicked on the Help Info button | ||
+ | Case $msg = $infoitem | ||
+ | MsgBox(64, "Info", "Arduino Communications Control v0.02" & @CRLF & "By: John Vaughters") | ||
+ | |||
+ | ; Check if user clicked on the "File" button | ||
+ | Case $msg = $file_btn | ||
+ | $working_dir = FileSelectFolder("Choose Folder...","",4,"") & "\" | ||
+ | GuiCtrlSetData($combo_ctl_working_dir, $working_dir) | ||
+ | |||
+ | Case $msg = $network_btn | ||
+ | $network_dir = FileSelectFolder("Choose Folder...","",4,"") & "\" | ||
+ | GuiCtrlSetData($combo_ctl_network_dir, $network_dir) | ||
+ | |||
+ | Case $msg = $search_btn | ||
+ | |||
+ | ; Start processing AVI | ||
+ | GUICtrlSetState ($processing, 1) | ||
+ | |||
+ | $file = FileOpen($working_dir & "command", 2) | ||
+ | ; Check if file opened for reading OK | ||
+ | If $file = -1 Then | ||
+ | MsgBox(0, "Error", "Unable to open file.") | ||
+ | Exit | ||
+ | EndIf | ||
+ | |||
+ | ; Set File Type | ||
+ | $working_file = GUICtrlRead($combo_ctl_search_file) | ||
+ | FileWrite($file, $working_file) | ||
+ | FileClose($file) ; The File must be closed before you can copy it anywhere | ||
+ | RunWait(@ComSpec & " /c " & "copy command " & $network_dir, $working_dir,@SW_HIDE) | ||
+ | $command_get_begin = TimerInit() ;Start the timer until you can retrieve your results | ||
+ | $process_results = True ; Set Processing flag | ||
+ | |||
+ | |||
+ | Case $msg = $site_btn | ||
+ | _IECreate ("www.combustory.com") | ||
+ | |||
+ | Case $msg = $clear_btn | ||
+ | _GUICtrlEdit_SetSel ($edit_ctl_tab2, 0, -1) | ||
+ | _GUICtrlEdit_ReplaceSel ($edit_ctl_tab2, "") | ||
+ | |||
+ | |||
+ | EndSelect | ||
+ | |||
+ | WEnd | ||
+ | |||
+ | </source> | ||
+ | |||
+ | ==== Step 11 ==== | ||
+ | ''' Put all the steps together and see if it works - ''' Well ok! I deviated from the quick guide, but if you follow this step and it WORKS! then you can revel. `,~) Now we just want to get it all to work. Check list of things that need to be in place: | ||
+ | * Make sure the Arduino is plugged into the linux box and that the Serial monitor on the Arduino environment is not connected | ||
+ | * Make sure you have loaded the Arduino program from Step 3 | ||
+ | * Now you are ready to start the ''CommandPoll'' script from Step 6 | ||
+ | * Make sure your Windows box can browse to the mapped drive and you can see the files on your linux box | ||
+ | * Start the ''Arduino_Com_v.01.au3'' program by pressing F5 and set the Network Dir to your mapped drive | ||
+ | * Change the Working Dir if you do not want to use the Desktop (optional) | ||
+ | * Now click the GO button and see if you get a response (it takes about 5 sec to respond) | ||
+ | |||
+ | '''If all goes well it will look something like this:''' | ||
+ | |||
+ | [[Image:arduino_com_pic_1.jpg]] | ||
+ | |||
+ | == ''PollCommand'' User Guide == | ||
+ | There is not much involved with the operation of this script. It basically looks for three files in the directory where it is started and responds to the existence of the file. | ||
+ | ==== Requirements ==== | ||
+ | This script requires that the ''Arduino-Serial'' program be compiled and in the same directory as the ''PollCommand'' script. | ||
+ | ==== ''command'' file ==== | ||
+ | When a ''command'' file is found in the directory, the script will send the contents of the file using the Arduino-Serial command to /dev/ttyUSB0. After the ''command'' file is sent, the script deletes the file. The basic usage is to copy a ''command'' file into the directory to be processed. | ||
+ | |||
+ | ==== ''clear_log'' file ==== | ||
+ | When a ''clear_log'' file is found in the directory it will clear the ''arduino_log'' file and then delete the ''clear_log'' file. The basic usage is to copy a ''clear_log'' file into the directory to be processed. | ||
+ | ==== ''exit_poll'' file ==== | ||
+ | When an ''exit_poll'' file is found in the directory it will close the ''tail'' process, delete the ''exit_poll'' file and then exit the script. The basic usage is to copy an ''exit_poll'' file into the directory to be processed. | ||
+ | |||
+ | == Arduino_Com_v.01 User Guide == | ||
+ | |||
+ | ==== Network Dir ==== | ||
+ | This is the place where you must find the Windows mapped drive and path to the folder where you placed the Arduino files on the Linux box. This location is where the ''PollCommand'' script is constantly polling for a command or clear_log file and this is where the the arduino_log file is located. | ||
+ | ==== Working Dir ==== | ||
+ | This particular path is fairly useless and you should be able to leave it as the desktop. All that happens here is that a results file is created until it is read into the Arduino_Com_v.01 software and then it is deleted. | ||
+ | ==== Arduino Command ==== | ||
+ | ''Basic Commands - ''The Arduino Commands data box is set up as a drop down menu with the pre-filled commands, but you can put whatever command you want in the box and then press the GO button to send the command. The commands are worth further explanation. The following commands will make the Arduino respond: | ||
+ | * C - will increment the Threshold value by the second digit. So a C5 will increment the Threshold by 5 points and a C9 will increment the Threshold by 9 points, and so on. If the second Character after the C is not a number, it will not increment the Threshold. The C command also prints out the Current Threshold value. | ||
+ | * D - will decrement the Threshold value by the second digit. So a D5 will decrement the Threshold by 5 points and a D9 will decrement the Threshold by 9 points, and so on. If the second Character after the D is not a number, it will not decrement the Threshold. The D command also prints out the Current Threshold value. | ||
+ | * T - will take a measurement of the current temperature and print out the current Temperature. A plain T will work without any second character. | ||
+ | |||
+ | All other commands are ignored by the Arduino, but you will get a result of the ascii values of any characters you send to the Arduino. A nice little ascii converter that came in handy when programming. Also you will notice several preceding characters and the last ascii character of each the command printed. These were for my testing and further development purposes. | ||
+ | |||
+ | ''Stacking Commands - '' You are also able to stack the commands together and they will be processed as individual commands. | ||
+ | |||
+ | For instance this command: | ||
+ | C5TD5 | ||
+ | will result with: | ||
+ | ------------------------------------------------------------------ | ||
+ | Command: C5TD5 | ||
+ | Results: | ||
+ | ~# THRESHOLD = 585 53 | ||
+ | ~& Temp = 520 84 | ||
+ | ~# THRESHOLD = 580 53 | ||
+ | ****************************************************************** | ||
+ | There can be no spaces in the commands. The command will only interpret the characters before the first space. | ||
+ | |||
+ | ==== Command Results ==== | ||
+ | This text box is where the results of your command will be loaded. There is also a result that will occur when the Temperature exceeds the threshold. This is something I was playing around with on how to handle alarms from the Arduino. So for this alarm you will get the results at the next command sent. | ||
+ | |||
+ | For instance the following result was given after the T command was sent: | ||
+ | |||
+ | ------------------------------------------------------------------ | ||
+ | Command: T | ||
+ | Results: | ||
+ | ~@ Hot Temp = 580 | ||
+ | ~@ Hot Temp = 580 | ||
+ | ~@ Hot Temp = 580 | ||
+ | ~@ Hot Temp = 580 | ||
+ | ~@ Hot Temp = 580 | ||
+ | ~& Temp = 577 84 | ||
+ | ****************************************************************** | ||
+ | This indicated that the threshold had been exceeded prior to the T command, and the Hot Temp alarms had been previously printed. | ||
+ | ==== Sys Info ==== | ||
+ | This Tab in the results location is just a typical text box I create for some basic info about the computer. | ||
+ | ==== Clear ==== | ||
+ | The Clear button will clear the Command Results text box and only the command results box. | ||
+ | |||
+ | == Troubleshooting == | ||
+ | === Summary === | ||
+ | When Troubleshooting a multi-functional issue, it is best practice to break down the issue into pieces and test each piece as a separate system. However, we will first run through a quick test to see if we can find any obvious issues first. | ||
+ | === Quick Test === | ||
+ | * '''Make sure the ''CommandPoll'' script is running - '''From the linux box, open up a terminal window and run the following command. | ||
+ | ps ax | grep PollCommand | ||
+ | You should get a result similar to this if the ''CommandPoll'' script is running: | ||
+ | 11763 ? S 0:00 /bin/bash /home/jvaughters/arduino-0011/sketchbook/ArduinoSerial/PollCommand | ||
+ | 11777 pts/0 S+ 0:00 grep PollCommand | ||
+ | If it is not running you will only get: | ||
+ | 11777 pts/0 S+ 0:00 grep PollCommand | ||
+ | If that is your result, then start the ''PollCommand'' script. I prefer to start it from an Xwindow by double clicking and then clicking RUN. | ||
+ | |||
+ | * '''Make sure the ''tail'' command is running as a process - '''From the terminal window type the following command. | ||
+ | ps ax | grep tail | ||
+ | You should get a result similar to this if the ''tail'' command is running: | ||
+ | 11770 ? S 0:00 tail -f /dev/ttyUSB0 | ||
+ | 12312 pts/0 S+ 0:00 grep tail | ||
+ | If it is not running you will only get: | ||
+ | 12312 pts/0 S+ 0:00 grep tail | ||
+ | If ''PollCommand'' is running and ''tail'' is not, then we have a bigger problem that will need to be investigated. | ||
+ | |||
+ | * '''Make sure your Arduino is using the /dev/ttyUSB0 terminal - ''' To check this open up your Arduino programming environment and go to the ''Tools>Serial Port'' menu and check for the /dev/ttyUSB0 entry. If it is not there then the best way to find out what serial port your system is using is to unplug the USB cable and then check the the ''Tools>Serial Port'' menu again, and one of the ports should have disappeared. Now put it back and look to see which new port is added. I the port is different then /dev/ttyUSB0 then you need to replace it with your device path in every location of the ''PollCommand'' script. | ||
+ | |||
+ | * '''Make sure your ''samba'' folder is shared and writable from windows - '''From your windows box browse to the ''samba'' shared drive and verify that you can copy a small file to that shared drive from windows. Also, make sure you have mapped the shared folder in windows to a drive and that you can browse and copy a file to that drive as well. If you cannot copy the small file to the shared drive, then check your folder permissions in linux as well as any possible restrictions in ''samba''. | ||
+ | === Isolating the Problem === | ||
+ | If everything checked out in the Quick Test and you are still having trouble getting results, then you probably need to isolate and test the individual components of the system. | ||
+ | ==== Linux Server ==== | ||
+ | On the Linux box we just want to make sure that we can get the ''PollCommand'' script to accomplish it's tasks. Below we break down each part of the script and test them individually. Each test is somewhat successive, so I recommend starting from the top and working down. | ||
+ | ===== Arduino Communication ===== | ||
+ | Let's verify the communication between the Arduino and the linux box. We can do this from a nice utility in the Arduino programming environment called the Serial Monitor. First we need to make sure the ''PollCommand'' script is not running. Use this command to check: | ||
+ | |||
+ | ps ax | grep PollCommand | ||
+ | If you get a result similar to this, then the ''CommandPoll'' script is running: | ||
+ | 11763 ? S 0:00 /bin/bash /home/jvaughters/arduino-0011/sketchbook/ArduinoSerial/PollCommand | ||
+ | 11777 pts/0 S+ 0:00 grep PollCommand | ||
+ | If it is not running you will only get: | ||
+ | 11777 pts/0 S+ 0:00 grep PollCommand | ||
+ | To stop the ''PollCommand'' script from running use this command in a terminal window and make sure you are in the same directory as the ''PollCommand'' script. | ||
+ | touch exit_poll | ||
+ | This command will create the file ''exit_poll'' and the existence of that file will make the ''PollCommand'' script exit. Check again to make sure the ''PollCommand'' script is not running. Also make sure that there are no ''tail'' commands running using this command: | ||
+ | ps ax | grep tail | ||
+ | You should get a result similar to this if the ''tail'' command is running: | ||
+ | 11770 ? S 0:00 tail -f /dev/ttyUSB0 | ||
+ | 12312 pts/0 S+ 0:00 grep tail | ||
+ | If it is not running you will only get: | ||
+ | 12312 pts/0 S+ 0:00 grep tail | ||
+ | To stop the ''tail'' commands from running try this command: | ||
+ | ps ax | grep "tail -f" | awk '{system("kill " $1)}' | ||
+ | This will kill all ''tail'' commands running, but unless you are using ''tail'' for some other reason it is safe to kill all the ''tail'' processes. | ||
+ | |||
+ | Now that we have the ''PollCommand'' script and the ''tail'' commands stopped, we can start the Serial Monitor in the Arduino programming environment by clicking the upper left button. This will give you a window in the bottom of the environment that will allow you to send and receive data to the Arduino board. make sure the baud is set to 57600, because it defaults to 9600, and my example uses 57600. Now you can type in the SEND box and click SEND to send data to the Arduino. If you have properly downloaded my example program, then you should get responses to commands sent. In the screen shot below I sent four commands: T, C5, D5, T (See description of commands in the User Guide section) | ||
+ | |||
+ | [[Image:arduino_serial_monitor.png]] | ||
+ | |||
+ | If you cannot get this to work, then change this line: | ||
+ | Serial.begin(57600); | ||
+ | With this line in your Arduino program: | ||
+ | Serial.begin(9600); | ||
+ | Now download the new program into the Arduino board, start the serial monitor again, and change the BAUD to 9600 and try the steps above again. If 9600 works and the 57600 does NOT work, then you will need to change any 57600 text in the ''CommandPoll'' script to 9600. If that still does not work, then you have bigger problems and need to make sure your Arduino install was clean. | ||
+ | |||
+ | ===== ''arduino-serial'' Command Test ===== | ||
+ | This step requires that you have successfully completed the Arduino Communications step above. If you were able to communicate via the Serial Monitor, then the next step is to verify an ''arduino-Serial'' command works. Open a terminal window and make sure you are in the shared folders where all of you files for this example reside. You also need to have the Serial Monitor in the Arduino set up and responding to sent commands. This time however, we will send the command from the command line in the terminal window using the ''arduino-serial'' command. The result will pop up in the Serial Monitor screen just as if you sent it from the Serial Monitor. I like to have the terminal window side-by-side with the Arduino environment when I do this test. Try this command: (Note: change the 57600 to 9600 if you are using that BAUD) | ||
+ | |||
+ | ./arduino-serial -b 57600 -p /dev/ttyUSB0 -s T | ||
+ | |||
+ | If this does not work, make sure you have a properly compiled ''arduino-serial'' program (See Step 5). Also make sure the /dev/ttyUSB0 is the same device that your system is using to communicate with the Arduino (See the Quick Test section for a way check the device). Try again until you get this to work. | ||
+ | ===== ''tail'' Command Test ===== | ||
+ | This test will verify that you are able to connect the Arduino as a terminal in linux. You will need to close the Serial Monitor in the Arduino environment by just clicking the Serial monitor button again. You should not see the BAUD setting or the SEND box when the Serial Monitor is off. You will need two terminal windows open and be in the directory where the example files are located. Again side-by-side is nice. Set the terminal settings with this command: (Note: change the 57600 to 9600 if you are using that BAUD) | ||
+ | stty -F /dev/ttyUSB0 cs8 57600 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke noflsh -ixon -crtscts | ||
+ | Now do this command to test the ''tail'' command: | ||
+ | tail -f /dev/tty/USB0 | ||
+ | After you hit enter, it will appear as though nothing happened, but you should see a blinking cursor. In any case go to the other terminal window and do this command:(Note: change the 57600 to 9600 if you are using that BAUD) | ||
+ | ./arduino-serial -b 57600 -p /dev/ttyUSB0 -s T | ||
+ | You should now see that results in the terminal window where you typed the ''tail'' command. If this does not work, make sure the /dev/ttyUSB0 is the same device that your system is using to communicate with the Arduino (See the Quick Test section for a way check the device). Try again until you get this to work. | ||
+ | |||
+ | To end the ''tail'' command just click into the terminal window where you typed the ''tail'' command and hit ctrl-c. | ||
+ | |||
+ | Assuming that worked, the next step would be to redirect the ''tail '' command to a file. Use this command: | ||
+ | tail -f /dev/ttyUSB0 >> arduino_log | ||
+ | Now use the arduino-serial command to send data again and then use this command to check if the file is recieving the data: | ||
+ | cat arduino_log | ||
+ | To clear the arduino_log file use this command: | ||
+ | echo > arduino_log | ||
+ | At this point I am going to point you to the ususal suspects for any issues, ie. BAUD and /dev/ttyUSB0 | ||
+ | |||
+ | You must be able to get this to work if you expect the overall system to work. | ||
+ | ===== ''samba'' ===== | ||
+ | Troubleshooting ''samba'' is way beyond the scope of this document. All I can say is that you need to make sure that the shared directory is set to Create and Delete permission for others. | ||
+ | ==== Windows Client ==== | ||
+ | On the Windows box we will want to make sure we can see the shared folder and that the mapped drive is working. One important note is if your network drive is not connected, or you have not listed it correctly in the Network Dir, the Arduino_Com_v.01 will crash. You will need to be able to copy files to the shared folder and mapped drive. For this section the ''PollCommand'' script should NOT be running. | ||
+ | ==== File Copy/Write Tests ==== | ||
+ | Open an explorer window or a command line window and go navigate to your mapped drive and path. Check the directory and make sure there is no ''command'' or ''clear_log'' files. Then start up the Arduino_Com_v.01 script and send a command. Now check that mapped directory and make sure the files ''command'' and ''clear_log'' are in the proper shared directory. If the Arduino_Com_v.01 script just shuts off, then it could not get to the Network Dir that you provided. If you provided the correct Network Dir and it still crashes then try to re-map the drive again. If the program does not shut down, and you do not see the files in the directory, then you probably have a valid location, but it is not the correct directory where the ''CommandPoll'' script is runs. | ||
− | + | [[Category:Electronics]] |
Latest revision as of 23:55, 12 February 2012
Welcome to Combustory
Any questions or comments:
- Send them to - combustor@combustory.com
|
Summary
In my search for methods to communicate with the Arduino board, I found lots of ways that required me to learn new languages or learn serial communication programming. I do want to eventually pick up these skills, but I found a quicker way for my needs. I have learned over time that you can always find a better way to solve a problem, but I realize that the amount of time to learn that better way is sometimes greater than the project time-frame, and therefore just solve it in the best way you can with the tools you have. I believe that the solution below encompasses that spirit. Here you will find a quick, dirty yet effective solution for communicating with the Arduino.
This solution met my goals, but it may not meet yours. It is limited in the effect that a transfer in a message may take as long as 5 sec. This fits fine for my needs where I am just looking to form a distributed network of smart sensors/controllers that allow the setting of certain variables and the reporting of alarms and/or useful tracking information from the individual controllers.
Note: I owe a BIG debt of gratitude to all the Arduino hackers that provided me with the tools/code/knowledge to allow this solution
Functional Description of the Method
This method creates a log file that is created by an Arduino board using serial communications that is sent to a terminal which is redirected to a file. The file can then be used by any software you desire to process the messages from the Arduino board. To send messages to the Arduino board the use of Arduino-Serial (a command line utility) is placed in a BASH script that is used to constantly poll for the existence of a command file. When a command file is found, the BASH script will send the commands in the file to the Arduino board. The response by the Arduino is to follow the command input and print response data out to the terminal, which is sent to the log file.
If your brain just got scrambled, join the club. There were several technical hurdles I was concerned about as soon as I thought of this method. I did not even think this would work at first, but it turns out to function just fine. (Until Further Notice! `,~)
In this diagram you will find the basic idea behind the method. This diagram is based on the example I provide below.
Requirements
The method requires the following hardware/knowledge:
- An Arduino Board or equivalent
- Linux computer that is able to communicate with the Arduino
- Your favorite development language
- Basic Linux operational skill
- Knowledge of samba or NFS if networking is desired
This example requires the following hardware/knowledge:
- An Arduino Board or equivalent (I used an actual Arduino Board with the USB connection)
- Linux computer that is able to communicate with the Arduino (I used an Ubuntu 8.x box)
- A Windows computer that is able to support AutoIT (I used an XP box)
- A network between the two computers
- Development languages - BASH scripting for Linux and AutoIT for windows
- Knowledge of samba for sharing folders over the network
Example of Method
Quick Guide:
Step 1 - Buy an Arduino Board - http://www.arduino.cc/en/Main/Buy
Step 2 - Load the Arduino software on your linux box - http://www.arduino.cc/playground/Learning/Linux
Step 3 - Load the sample Arduino code (see Step 3 below) into your Arduino board - http://www.arduino.cc/en/Guide/HomePage
Step 4 - Create a Folder on the Linux box and share the Folder over the network using samba - http://us1.samba.org/samba/
Step 5 - Compile the Arduino-Serial software and place the executable in the shared folder from Step 4 - http://todbot.com/blog/2006/12/06/arduino-serial-c-code-to-talk-to-arduino/
Step 6 - Load the sample BASH scripting text (see Step 6 below) into an executable file in your shared folder from Step 4 on the Linux box - http://www.gnu.org/software/bash/
Step 7 - Build your Thermistor circuit based on the diagram (see Step 7 below) or something similar
Step 8 - Map your 'samba' shared folder on your linux box to a windows drive
Step 9 - Load AutoIT on your windows box - http://www.autoitscript.com/autoit3/
Step 10 - Use the sample AutoIT script (see Step 10 below) to test the solution
Step 11 - Revel in your new found capability to conquer the world, well the Arduino world anyway! `,~)
Detailed Guide:
Step 1
Buy an Arduino Board - There are lots of options to buy a board. I chose the standard USB version from the guidance of this Arduino link. If you follow this Freeduino link you will find many options including my favorite the Bare Bones Board from moderndevice.com and wulfden.com. Check out the RBBB assembly. These options are super cheap and I will definitely be buying my next Arduino based board from these sites. These folks have knocked down the price of micro-controller development boards.
Step 2
Load the Arduino software on your linux box - Here are the Linux Instructions. For my Arduino, I used Ubuntu 8.x. I also recommend you do a google search of Arduino and your linux type to find any type of specific hiccups that inevitably find there way into installs. The Ubuntu instuctions I ended up using was from principialabs.com and after all was said and done these instructions worked without a single problem for me.
Step 3
Load the sample Arduino code into your Arduino board - Here is the code I used. I will not claim it to be pretty, but it does work as a test for this method. Most likely you will have to modify some of the numbers around the input. I will give you my schematic, but I am sure that your set up will vary somewhat and that will change the Threshold and Voltage reading numbers.
/* * AnalogInput with Thermistor * by DojoDave <http://www.0j0.org> and John Vaughters <http://www.combustory.com> * * Turns on a light emitting diode(LED) connected to digital * pin 13 when the temperature rises above the threshold. The value obtained by analogRead(). * In the easiest case we connect a thermistor to analog pin 5. The program also implements a * Serial Communication method that utilizes a char and a # ie. A0...A9, B0...B9, etc. Each Command will implement * a specific action in the Arduino. * */ int tempPin = 5; // select the input pin for the Thermistor int ledPin = 13; // select the pin for the LED int val = 0; // variable to store the value coming from the sensor int THRESHOLD = 580; int statePin = HIGH; // variable used to store the last LED status, to toggle the light int command = 0; // This is the command char, in ascii form, sent from the serial port long polTime = 1000; // The time to Pol the tempPin long previousMillis = 0; // will store last time Temp was updated void setup() { Serial.begin(57600); pinMode(ledPin, OUTPUT); // declare the ledPin as an OUTPUT pinMode(12, OUTPUT); // Test Com Reset issue digitalWrite(12,HIGH); delay(5000); digitalWrite(12,LOW); } void loop() { if (millis() - previousMillis > polTime) { previousMillis = millis(); // remember the last time val = analogRead(tempPin); // read the value from the sensor if (val >= THRESHOLD) { //statePin = !statePin; // toggle the status of the ledPin (this trick doesn't use time cycles) digitalWrite(ledPin, statePin); // turn the led on or off Serial.print("~@ Hot "); // send the string "Hot" back to the computer, followed by newline Serial.print("Temp = "); Serial.println(val); // } else { digitalWrite(ledPin, LOW); } if (Serial.available()) { // Look for char in serial que and process if found command = Serial.read(); if (command == 84) { // If command = "T" print the Temp Serial.print("~& Temp = "); Serial.print(val); // Serial.print(" "); delay(100); } else if (command == 67) { //If command = "C" Change Temp Threshhold if (Serial.available()) { command = Serial.read(); if (command > 47 && command < 58) { // If command is between 0-9 Increment the Threshold by number sent THRESHOLD += command - 48; // ASII math to get value sent Serial.print("~# THRESHOLD = "); Serial.print(THRESHOLD); // Serial.print(" "); delay(100); } } } else if (command == 68) { //If command = "D" Change Temp Threshhold if (Serial.available()) { command = Serial.read(); if (command > 47 && command < 58) { // If command is between 0-9 Decrement the Threshold by number sent THRESHOLD -= command - 48; // ASII math to get value sent Serial.print("~# THRESHOLD = "); Serial.print(THRESHOLD); // Serial.print(" "); delay(100); } } } delay(100); Serial.println(command); // Echo command char found in serial que command = 0; // reset command } } } //*****************************************************The End***********************
Step 4
Create a Folder on the Linux box and share the Folder over the network using samba - There is not much to say here other than learn your samba and make it happen. There are literally tons of info on this subject on the web. Other than that make sure that the permissions are set on the shared folder to allow creating and writing files.
Step 5
Compile the Arduino-Serial software and place the executable in the shared folder from Step 4 - This step gave me a little bit of an issue. I had to comment out a few baud speed lines. It was not that difficult to figure out, because the compiler gave pretty clear error messages and these Arduino-Serial instructions even mentioned this as an issue and even though it is mentioned and supposedly fixed, there is still one more line he did not comment out. Make sure any line that looks like this:
case 28800: brate=B28800; break;
Looks like this:
//case 28800: brate=B28800; break;
Step 6
Load the sample BASH scripting text into an executable file in your shared folder from Step 4 on the Linux box - Here is the BASH script. It is a script that goes into an infinite loop and constantly polls for two files, a command file and a clear_log file. When it sees those files it takes action to either send commands or clear the log file. The files are sent from some other application that are used to control the communication to the Arduino. In this example I use AutoIT as the controlling software (See Step 9). I will leave it to the reader to decode these commands.
#!/bin/bash # File name CommandPoll # This Script is used to control the communication to an Arduino board via the Arduino-Serial command line utility and the dev/ttyUSB0 terminal # Written by John Vaughters <http://www.combustory.com> # Set the terminal to match the Arduino Serial Communications stty -F /dev/ttyUSB0 cs8 57600 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke noflsh -ixon -crtscts # Kill any existing tail commands logging the terminal exec ps ax | grep "tail -f /dev/ttyUSB0" | grep ? | awk '{system("kill " $1)}' # Connect the terminal to a tail logging to a file by appending exec tail -f /dev/ttyUSB0 >> /home/jvaughters/arduino-0011/sketchbook/ArduinoSerial/arduino_log & # create an infinite loop to test for files that will prompt action while [ 1 ] do if [ -f command ] # Does the command file exist then cat command | awk '{system("./arduino-serial -b 57600 -p /dev/ttyUSB0 -s " $1)}' # Send the commands in the command file via Arduino-Serial utility rm command # remove the command file fi if [ -f clear_log ] # Does the clear_log file exist then echo > arduino_log rm clear_log fi if [ -f exit_poll ] # Does the exit_poll file exist then # Kill any tail commands logging the terminal exec ps ax | grep "tail -f /dev/ttyUSB0" | grep ? | awk '{system("kill " $1)}' rm exit_poll exit 0 # Exit CommandPoll script fi sleep 1 # Sleep for one second or your processor will run 100% (optional) done exit 0
Step 7
Build your Thermistor and LED circuits based on the diagrams or something similar - That's it, just follow the diagrams or create a comparable solution.
Step 8
Map your samba linux shared folder to a windows drive - For this example you have to map a drive on your windows box. I think I will leave the details on how to accomplish this task to a google search on mapping drives in windows. It is fairly straight forward. I mapped my drive to P: for no particular reason, but what ever you map it to, you will be able to select the drive from within the AutoIT GUI.
Step 9
Load AutoIT on your windows box - Go to the AutoIT site and load this very powerful and free software. This software has been around for a while and it has a fairly active development crew, which creates constant improvements, extensions and user libraries. It is a very powerful GUI scripting tool and it is very easy to create a GUI application as well. I have created many great utilities using this software. It is not for super powerful software needs, but with today's computers, it does quite a bit. LOVE this tool.
Step 10
Use the sample AutoIT script to test the solution - This code is a utility that will allow you to select the mapped shared windows drive/path and a working directory. There is a drop down menu with four commands that that will make the Arduino respond. This program will create a command file, fill it with the command string and place it in the Network Dir. The Software will wait 5 seconds and then retrieve the results and place it in the text window. Then the program will place the clear_log file in the Network Dir. I will not cover the use of this software here, refer to the User Guide section. For now just get this loaded into AutoIT and hit F5 to get it to run. You can run AutoIT programs interpreted or compiled. Pressing F5 runs it as interpreted.
; Arduino Communications and Control ; File name: Arduino_Com_v.02.au3 ; 31 Jul 2008 - John Vaughters <http://www.combustory.com> ; This is a Utility to Communicate with the Arduino Control board #include <WindowsConstants.au3> ; added to resolve issue with AutoIT v 3.3 #include <GuiConstants.au3> #include <GuiEdit.au3> #include <file.au3> #include <Date.au3> #include <IE.au3> ;************* ; _Load_Results() loads the temp file into the desired control then deletes the temp file ; $w_dir is the working directory where the file exists ; $ctl_to_load is the place to load the file contents ; $temp_file is the temporary file to load the data from ; The function returns the number of lines loaded from the file Func _Load_Results ($w_dir, $ctl_load_to, $temp_file) Dim $aRecords If Not _FileReadToArray($w_dir & $temp_file,$aRecords) Then MsgBox(4096,"Error", " Error reading log to Array error:" & @error) Exit EndIf For $x = 1 to $aRecords[0] if StringLen($aRecords[$x]) > 0 then GuiCtrlSetData($ctl_load_to, $aRecords[$x] & @CRLF, 1) Next ;Delete the temporary file RunWait(@ComSpec & " /c " & "del " & $temp_file, $w_dir & "",@SW_HIDE) Return ($aRecords[0]-1) EndFunc ;Initialize Variable Defaults $working_dir = @DesktopDir & "\" $working_file = "arduino_log" $poll_delay = 5000 ; This is the delay the program waits before collecting the command results $network_dir = "P:\" ; Default network directory $process_results = False ;Processing Flag $command_get_begin = TimerInit() ;Initialize Timer ; GUI GuiCreate(" Arduino Communications and Control", 700, 600) ; MENU $filemenu = GuiCtrlCreateMenu("&File") $fileitem = GUICtrlCreateMenuitem ("Open",$filemenu) GUICtrlSetState(-1,$GUI_DEFBUTTON) $exititem = GUICtrlCreateMenuitem ("Exit",$filemenu) $helpmenu = GuiCtrlCreateMenu("Help") $infoitem = GUICtrlCreateMenuitem ("Info",$helpmenu) ; LOGO PIC GuiCtrlCreatePic("logo.jpg",0,0, 100,140) ; AVI for letting the user know the system is processing $processing = GuiCtrlCreateAvi("sampleAVI.avi",0, 405, 140, 32, 32) ; Tabbed Result Window $tab_result_start_x = 20 $tab_result_start_y = 175 $tab_result_size_x = 650 $tab_result_size_y = 400 $tab_result_title_2 = "Command Results" $tab_result_title_4 = "Sys Info" GuiCtrlCreateTab($tab_result_start_x, $tab_result_start_y, $tab_result_size_x , $tab_result_size_y) GuiCtrlCreateTabItem($tab_result_title_2) $edit_ctl_tab2 = GuiCtrlCreateEdit(@CRLF & "", $tab_result_start_x + 10 , $tab_result_start_y + 40, $tab_result_size_x - 20, $tab_result_size_y - 50) GuiCtrlCreateTabItem($tab_result_title_4) $edit_ctl_tab4 = GuiCtrlCreateEdit(@CRLF & "", $tab_result_start_x + 10 , $tab_result_start_y + 40, $tab_result_size_x - 20, $tab_result_size_y - 50) GuiCtrlCreateTabItem("") ; Combo Arduino Command File Type $combo_ctl_search_file = GuiCtrlCreatecombo("*", 240, 145, 120, 100) GUICtrlSetData(-1,"C5|D5|T1|","C5") ; add other item snd set a new default GuiCtrlCreateLabel("Arduino Command", 245, 170, 150, 20) ; Current Working Directory Label $combo_ctl_working_dir = GuiCtrlCreateLabel($working_dir, 240, 80, 450, 22,$WS_DLGFRAME) GUICtrlSetBkColor(-1,0xffffff) GuiCtrlCreateLabel("Working Directory", 245, 105, 200, 20) ; Current Network Directory Label $combo_ctl_network_dir = GuiCtrlCreateLabel($network_dir, 240, 20, 450, 22,$WS_DLGFRAME) GUICtrlSetBkColor(-1,0xffffff) GuiCtrlCreateLabel("Network Directory", 245, 45, 200, 20) ; BUTTON $search_btn = GuiCtrlCreateButton("Go", 370, 143, 25, 25) $file_btn = GuiCtrlCreateButton("Working Dir", 125, 77, 100, 25) $network_btn = GuiCtrlCreateButton("Network Dir", 125, 18, 100, 25) $site_btn = GuiCtrlCreateButton("www.combustory.com", 0, 145, 135, 22) $clear_btn = GuiCtrlCreateButton("Clear", 620, 170, 50, 22) ; List System Info GuiCtrlSetData($edit_ctl_tab4, "Computer: " & @CRLF & _ "----------------------------------------------------------" & @CRLF & _ "IP Address: " & @IPAddress1 & @CRLF & _ "Computer Name: " & @ComputerName & @CRLF & _ "OS: " & @OSVersion & @CRLF & _ "Sys Dir: " & @SystemDir & @CRLF & @CRLF) ; GUI MESSAGE LOOP GuiSetState() ; Main Event Loop While 1 ; After every loop check if the user clicked something in the GUI window $msg = GUIGetMsg() if $process_results = True Then if $poll_delay < TimerDiff($command_get_begin) Then RunWait(@ComSpec & " /c " & "type arduino_log>results.txt", $network_dir,@SW_HIDE) ; Load command results into Command Results tab GuiCtrlSetData($edit_ctl_tab2, "------------------------------------------------------------------" & @CRLF,1) GuiCtrlSetData($edit_ctl_tab2, "Command: " & GUICtrlRead($combo_ctl_search_file) & @CRLF,1) GuiCtrlSetData($edit_ctl_tab2, "Results: " & @CRLF,1) _Load_Results ($network_dir, $edit_ctl_tab2, "results.txt") GuiCtrlSetData($edit_ctl_tab2, "******************************************************************" & @CRLF,1) $process_results = False RunWait(@ComSpec & " /c " & "echo>clear_log", $network_dir,@SW_HIDE) ; Send message to Linux polling script to clear the log GUICtrlSetState ($processing, 0) EndIf EndIf Select ; Check if user clicked on the close button Case $msg = $GUI_EVENT_CLOSE Or $msg = $exititem ; Destroy the GUI including the controls GUIDelete() ; Exit the script Exit ; Check if user clicked on the File Open button Case $msg = $fileitem $working_dir = FileSelectFolder("Choose Folder...","",4,"") & "\" GuiCtrlSetData($combo_ctl_working_dir, $working_dir) ; Check if user clicked on the Help Info button Case $msg = $infoitem MsgBox(64, "Info", "Arduino Communications Control v0.02" & @CRLF & "By: John Vaughters") ; Check if user clicked on the "File" button Case $msg = $file_btn $working_dir = FileSelectFolder("Choose Folder...","",4,"") & "\" GuiCtrlSetData($combo_ctl_working_dir, $working_dir) Case $msg = $network_btn $network_dir = FileSelectFolder("Choose Folder...","",4,"") & "\" GuiCtrlSetData($combo_ctl_network_dir, $network_dir) Case $msg = $search_btn ; Start processing AVI GUICtrlSetState ($processing, 1) $file = FileOpen($working_dir & "command", 2) ; Check if file opened for reading OK If $file = -1 Then MsgBox(0, "Error", "Unable to open file.") Exit EndIf ; Set File Type $working_file = GUICtrlRead($combo_ctl_search_file) FileWrite($file, $working_file) FileClose($file) ; The File must be closed before you can copy it anywhere RunWait(@ComSpec & " /c " & "copy command " & $network_dir, $working_dir,@SW_HIDE) $command_get_begin = TimerInit() ;Start the timer until you can retrieve your results $process_results = True ; Set Processing flag Case $msg = $site_btn _IECreate ("www.combustory.com") Case $msg = $clear_btn _GUICtrlEdit_SetSel ($edit_ctl_tab2, 0, -1) _GUICtrlEdit_ReplaceSel ($edit_ctl_tab2, "") EndSelect WEnd
Step 11
Put all the steps together and see if it works - Well ok! I deviated from the quick guide, but if you follow this step and it WORKS! then you can revel. `,~) Now we just want to get it all to work. Check list of things that need to be in place:
- Make sure the Arduino is plugged into the linux box and that the Serial monitor on the Arduino environment is not connected
- Make sure you have loaded the Arduino program from Step 3
- Now you are ready to start the CommandPoll script from Step 6
- Make sure your Windows box can browse to the mapped drive and you can see the files on your linux box
- Start the Arduino_Com_v.01.au3 program by pressing F5 and set the Network Dir to your mapped drive
- Change the Working Dir if you do not want to use the Desktop (optional)
- Now click the GO button and see if you get a response (it takes about 5 sec to respond)
If all goes well it will look something like this:
PollCommand User Guide
There is not much involved with the operation of this script. It basically looks for three files in the directory where it is started and responds to the existence of the file.
Requirements
This script requires that the Arduino-Serial program be compiled and in the same directory as the PollCommand script.
command file
When a command file is found in the directory, the script will send the contents of the file using the Arduino-Serial command to /dev/ttyUSB0. After the command file is sent, the script deletes the file. The basic usage is to copy a command file into the directory to be processed.
clear_log file
When a clear_log file is found in the directory it will clear the arduino_log file and then delete the clear_log file. The basic usage is to copy a clear_log file into the directory to be processed.
exit_poll file
When an exit_poll file is found in the directory it will close the tail process, delete the exit_poll file and then exit the script. The basic usage is to copy an exit_poll file into the directory to be processed.
Arduino_Com_v.01 User Guide
Network Dir
This is the place where you must find the Windows mapped drive and path to the folder where you placed the Arduino files on the Linux box. This location is where the PollCommand script is constantly polling for a command or clear_log file and this is where the the arduino_log file is located.
Working Dir
This particular path is fairly useless and you should be able to leave it as the desktop. All that happens here is that a results file is created until it is read into the Arduino_Com_v.01 software and then it is deleted.
Arduino Command
Basic Commands - The Arduino Commands data box is set up as a drop down menu with the pre-filled commands, but you can put whatever command you want in the box and then press the GO button to send the command. The commands are worth further explanation. The following commands will make the Arduino respond:
- C - will increment the Threshold value by the second digit. So a C5 will increment the Threshold by 5 points and a C9 will increment the Threshold by 9 points, and so on. If the second Character after the C is not a number, it will not increment the Threshold. The C command also prints out the Current Threshold value.
- D - will decrement the Threshold value by the second digit. So a D5 will decrement the Threshold by 5 points and a D9 will decrement the Threshold by 9 points, and so on. If the second Character after the D is not a number, it will not decrement the Threshold. The D command also prints out the Current Threshold value.
- T - will take a measurement of the current temperature and print out the current Temperature. A plain T will work without any second character.
All other commands are ignored by the Arduino, but you will get a result of the ascii values of any characters you send to the Arduino. A nice little ascii converter that came in handy when programming. Also you will notice several preceding characters and the last ascii character of each the command printed. These were for my testing and further development purposes.
Stacking Commands - You are also able to stack the commands together and they will be processed as individual commands.
For instance this command:
C5TD5
will result with:
------------------------------------------------------------------ Command: C5TD5 Results: ~# THRESHOLD = 585 53 ~& Temp = 520 84 ~# THRESHOLD = 580 53 ******************************************************************
There can be no spaces in the commands. The command will only interpret the characters before the first space.
Command Results
This text box is where the results of your command will be loaded. There is also a result that will occur when the Temperature exceeds the threshold. This is something I was playing around with on how to handle alarms from the Arduino. So for this alarm you will get the results at the next command sent.
For instance the following result was given after the T command was sent:
------------------------------------------------------------------ Command: T Results: ~@ Hot Temp = 580 ~@ Hot Temp = 580 ~@ Hot Temp = 580 ~@ Hot Temp = 580 ~@ Hot Temp = 580 ~& Temp = 577 84 ******************************************************************
This indicated that the threshold had been exceeded prior to the T command, and the Hot Temp alarms had been previously printed.
Sys Info
This Tab in the results location is just a typical text box I create for some basic info about the computer.
Clear
The Clear button will clear the Command Results text box and only the command results box.
Troubleshooting
Summary
When Troubleshooting a multi-functional issue, it is best practice to break down the issue into pieces and test each piece as a separate system. However, we will first run through a quick test to see if we can find any obvious issues first.
Quick Test
- Make sure the CommandPoll script is running - From the linux box, open up a terminal window and run the following command.
ps ax | grep PollCommand
You should get a result similar to this if the CommandPoll script is running:
11763 ? S 0:00 /bin/bash /home/jvaughters/arduino-0011/sketchbook/ArduinoSerial/PollCommand 11777 pts/0 S+ 0:00 grep PollCommand
If it is not running you will only get:
11777 pts/0 S+ 0:00 grep PollCommand
If that is your result, then start the PollCommand script. I prefer to start it from an Xwindow by double clicking and then clicking RUN.
- Make sure the tail command is running as a process - From the terminal window type the following command.
ps ax | grep tail
You should get a result similar to this if the tail command is running:
11770 ? S 0:00 tail -f /dev/ttyUSB0 12312 pts/0 S+ 0:00 grep tail
If it is not running you will only get:
12312 pts/0 S+ 0:00 grep tail
If PollCommand is running and tail is not, then we have a bigger problem that will need to be investigated.
- Make sure your Arduino is using the /dev/ttyUSB0 terminal - To check this open up your Arduino programming environment and go to the Tools>Serial Port menu and check for the /dev/ttyUSB0 entry. If it is not there then the best way to find out what serial port your system is using is to unplug the USB cable and then check the the Tools>Serial Port menu again, and one of the ports should have disappeared. Now put it back and look to see which new port is added. I the port is different then /dev/ttyUSB0 then you need to replace it with your device path in every location of the PollCommand script.
- Make sure your samba folder is shared and writable from windows - From your windows box browse to the samba shared drive and verify that you can copy a small file to that shared drive from windows. Also, make sure you have mapped the shared folder in windows to a drive and that you can browse and copy a file to that drive as well. If you cannot copy the small file to the shared drive, then check your folder permissions in linux as well as any possible restrictions in samba.
Isolating the Problem
If everything checked out in the Quick Test and you are still having trouble getting results, then you probably need to isolate and test the individual components of the system.
Linux Server
On the Linux box we just want to make sure that we can get the PollCommand script to accomplish it's tasks. Below we break down each part of the script and test them individually. Each test is somewhat successive, so I recommend starting from the top and working down.
Arduino Communication
Let's verify the communication between the Arduino and the linux box. We can do this from a nice utility in the Arduino programming environment called the Serial Monitor. First we need to make sure the PollCommand script is not running. Use this command to check:
ps ax | grep PollCommand
If you get a result similar to this, then the CommandPoll script is running:
11763 ? S 0:00 /bin/bash /home/jvaughters/arduino-0011/sketchbook/ArduinoSerial/PollCommand 11777 pts/0 S+ 0:00 grep PollCommand
If it is not running you will only get:
11777 pts/0 S+ 0:00 grep PollCommand
To stop the PollCommand script from running use this command in a terminal window and make sure you are in the same directory as the PollCommand script.
touch exit_poll
This command will create the file exit_poll and the existence of that file will make the PollCommand script exit. Check again to make sure the PollCommand script is not running. Also make sure that there are no tail commands running using this command:
ps ax | grep tail
You should get a result similar to this if the tail command is running:
11770 ? S 0:00 tail -f /dev/ttyUSB0 12312 pts/0 S+ 0:00 grep tail
If it is not running you will only get:
12312 pts/0 S+ 0:00 grep tail
To stop the tail commands from running try this command:
ps ax | grep "tail -f" | awk '{system("kill " $1)}'
This will kill all tail commands running, but unless you are using tail for some other reason it is safe to kill all the tail processes.
Now that we have the PollCommand script and the tail commands stopped, we can start the Serial Monitor in the Arduino programming environment by clicking the upper left button. This will give you a window in the bottom of the environment that will allow you to send and receive data to the Arduino board. make sure the baud is set to 57600, because it defaults to 9600, and my example uses 57600. Now you can type in the SEND box and click SEND to send data to the Arduino. If you have properly downloaded my example program, then you should get responses to commands sent. In the screen shot below I sent four commands: T, C5, D5, T (See description of commands in the User Guide section)
If you cannot get this to work, then change this line:
Serial.begin(57600);
With this line in your Arduino program:
Serial.begin(9600);
Now download the new program into the Arduino board, start the serial monitor again, and change the BAUD to 9600 and try the steps above again. If 9600 works and the 57600 does NOT work, then you will need to change any 57600 text in the CommandPoll script to 9600. If that still does not work, then you have bigger problems and need to make sure your Arduino install was clean.
arduino-serial Command Test
This step requires that you have successfully completed the Arduino Communications step above. If you were able to communicate via the Serial Monitor, then the next step is to verify an arduino-Serial command works. Open a terminal window and make sure you are in the shared folders where all of you files for this example reside. You also need to have the Serial Monitor in the Arduino set up and responding to sent commands. This time however, we will send the command from the command line in the terminal window using the arduino-serial command. The result will pop up in the Serial Monitor screen just as if you sent it from the Serial Monitor. I like to have the terminal window side-by-side with the Arduino environment when I do this test. Try this command: (Note: change the 57600 to 9600 if you are using that BAUD)
./arduino-serial -b 57600 -p /dev/ttyUSB0 -s T
If this does not work, make sure you have a properly compiled arduino-serial program (See Step 5). Also make sure the /dev/ttyUSB0 is the same device that your system is using to communicate with the Arduino (See the Quick Test section for a way check the device). Try again until you get this to work.
tail Command Test
This test will verify that you are able to connect the Arduino as a terminal in linux. You will need to close the Serial Monitor in the Arduino environment by just clicking the Serial monitor button again. You should not see the BAUD setting or the SEND box when the Serial Monitor is off. You will need two terminal windows open and be in the directory where the example files are located. Again side-by-side is nice. Set the terminal settings with this command: (Note: change the 57600 to 9600 if you are using that BAUD)
stty -F /dev/ttyUSB0 cs8 57600 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke noflsh -ixon -crtscts
Now do this command to test the tail command:
tail -f /dev/tty/USB0
After you hit enter, it will appear as though nothing happened, but you should see a blinking cursor. In any case go to the other terminal window and do this command:(Note: change the 57600 to 9600 if you are using that BAUD)
./arduino-serial -b 57600 -p /dev/ttyUSB0 -s T
You should now see that results in the terminal window where you typed the tail command. If this does not work, make sure the /dev/ttyUSB0 is the same device that your system is using to communicate with the Arduino (See the Quick Test section for a way check the device). Try again until you get this to work.
To end the tail command just click into the terminal window where you typed the tail command and hit ctrl-c.
Assuming that worked, the next step would be to redirect the tail command to a file. Use this command:
tail -f /dev/ttyUSB0 >> arduino_log
Now use the arduino-serial command to send data again and then use this command to check if the file is recieving the data:
cat arduino_log
To clear the arduino_log file use this command:
echo > arduino_log
At this point I am going to point you to the ususal suspects for any issues, ie. BAUD and /dev/ttyUSB0
You must be able to get this to work if you expect the overall system to work.
samba
Troubleshooting samba is way beyond the scope of this document. All I can say is that you need to make sure that the shared directory is set to Create and Delete permission for others.
Windows Client
On the Windows box we will want to make sure we can see the shared folder and that the mapped drive is working. One important note is if your network drive is not connected, or you have not listed it correctly in the Network Dir, the Arduino_Com_v.01 will crash. You will need to be able to copy files to the shared folder and mapped drive. For this section the PollCommand script should NOT be running.
File Copy/Write Tests
Open an explorer window or a command line window and go navigate to your mapped drive and path. Check the directory and make sure there is no command or clear_log files. Then start up the Arduino_Com_v.01 script and send a command. Now check that mapped directory and make sure the files command and clear_log are in the proper shared directory. If the Arduino_Com_v.01 script just shuts off, then it could not get to the Network Dir that you provided. If you provided the correct Network Dir and it still crashes then try to re-map the drive again. If the program does not shut down, and you do not see the files in the directory, then you probably have a valid location, but it is not the correct directory where the CommandPoll script is runs.