Skip to content

Commit 464ba8c

Browse files
committed
Update custom ruggeduino page for SR2022
1 parent 6d8aca4 commit 464ba8c

File tree

1 file changed

+16
-177
lines changed

1 file changed

+16
-177
lines changed

programming/sr/ruggeduinos/custom_firmware.md

Lines changed: 16 additions & 177 deletions
Original file line numberDiff line numberDiff line change
@@ -12,31 +12,15 @@ This documentation refers to a feature which is only available on the physical r
1212

1313
The Ruggeduino that came as part of your kit was shipped with a firmware that provides the functionality outlined in the [Ruggeduino](/docs/programming/sr/ruggeduinos) page.
1414
You may wish to extend the functionality of this firmware, or completely replace it.
15-
The `sr.robot` library provides support for three Ruggeduino firmware scenarios:
15+
The `sr.robot3` library provides support for three Ruggeduino firmware scenarios:
1616

1717
1. Default SR firmware
1818
2. [Extended SR firmware](#extension): Firmwares that add commands to the default SR firmware.
1919
3. [Completely custom](#completely): Any firmware not derived from the SR firmware.
2020

21-
By default, the [`sr.robot`](/docs/programming/sr/) library assumes that all connected Ruggeduinos are running the SR firmware.
21+
By default, the [`sr.robot3`](/docs/programming/sr/) library assumes that all connected Ruggeduinos are running the SR firmware.
2222
If you wish to use an extended SR firmware, or completely custom firmware,
2323
then you need to tell the `Robot` object what to do with your Ruggeduino(s).
24-
To do this, you will need to expand the initialisation of your `Robot` object as detailed [here](/docs/programming/sr/#CustomRobotInit).
25-
Your code will then look something like this:
26-
27-
~~~~~ python
28-
from sr.robot import *
29-
30-
R = Robot.setup()
31-
32-
R.init()
33-
34-
R.wait_start()
35-
36-
# The rest of your code
37-
~~~~~
38-
39-
The next step depends on whether you are running an extended SR firmware, or a completely custom firmware.
4024

4125
[Extension of the SR firmware](#extension) {#extension}
4226
------------------------------
@@ -95,149 +79,20 @@ Your command can read additional data from the serial port if it requires additi
9579
It can also write a response back to the host (your Python code).
9680
Have a look at the `command_read()` function to see how to do this.
9781

98-
### Step 2: Extend the `Ruggeduino` class
99-
100-
Your robot's python code will, by default, use a `Ruggeduino` object to communicate with the Ruggeduino.
101-
The object returned to you when you type `R.ruggeduinos[0]` is a `Ruggeduino` instance.
102-
This object knows how to talk to the default command handlers in the SR firmware.
103-
104-
<div class="info" markdown="1">
105-
Don't worry if you don't know what "object" means -- you can probably blag this without knowing!
106-
If you do want to know about them, you'll find introductions to them all over the web.
107-
You could try [this one](http://www.jesshamrick.com/2011/05/18/an-introduction-to-classes-and-inheritance-in-python/), for example.
108-
</div>
109-
110-
You'll need to extend the `Ruggeduino` class, giving it at least one extra method to perform your command.
111-
Start by adding this to your code:
112-
113-
~~~~~ python
114-
from sr.robot import *
115-
116-
class CustomisedRuggeduino(Ruggeduino):
117-
pass
118-
~~~~~
119-
120-
You've just declared a class called `CustomisedRuggeduino` (you will probably want to call it something else that makes more sense in your application).
121-
At the moment, it behaves in exactly the same way as the `Ruggeduino` class.
122-
You now need to add your custom method to it:
123-
124-
~~~~~ python
125-
from sr.robot import *
126-
127-
class CustomisedRuggeduino(Ruggeduino):
128-
129-
# Your function for instructing a Ruggeduino to bake a cake
130-
def bake_cake(self):
131-
with self.lock:
132-
self.command("c")
133-
~~~~~
134-
135-
Skipping ahead for a moment: Once we've told your `Robot` object about this `CustomisedRuggeduino`
136-
class (which we do in the next step), you will be able to do this:
137-
138-
~~~~~ python
139-
R.ruggeduinos[0].bake_cake()
140-
# and you'll still be able to do this:
141-
R.ruggeduinos[0].digital_read(3)
142-
~~~~~
143-
144-
<div class="warning" markdown="1">
145-
The IDE will unfortunately error about the lack of a `bake_cake` method (or your equivalent) in the above code.
146-
This is an expected restriction of the way the IDE checks the syntax of your code.
147-
148-
You can therefore ignore these errors (though you should be careful that the error is one of these and not something else).
149-
</div>
150-
151-
#### `with self.lock:`
152-
153-
You'll notice that the code above contains a line that reads:
154-
155-
~~~~~ python
156-
with self.lock:
157-
~~~~~
158-
159-
Whenever you call `self.command`, you need to ensure that it is called within a block of code headed by this `with` statement.
160-
This is a tool that makes your code "thread-safe".
161-
If you're not using threads, then you will still need to use it, but it won't affect the behaviour of your program.
82+
### Step 2: Use your new command from Python
16283

163-
#### Responses
164-
165-
The response from your command is returned by the `self.command` function.
166-
Remember that it will be a string, so you will need to convert it as necessary.
167-
168-
If, for example, our cake-baking function on our Ruggeduino responds with the number of cakes that were baked, then we could do this:
84+
You can send a custom command from your Python code to the Ruggeduino to control your cake-baking.
16985

17086
~~~~~ python
171-
class CustomisedRuggeduino(Ruggeduino):
172-
173-
def bake_cake(self):
174-
with self.lock:
175-
resp = self.command("c")
176-
return int(resp)
87+
cake_result = R.ruggeduino.command("c")
17788
~~~~~
17889

179-
180-
### Step 3: Tell the `Robot` to use your extended class
181-
182-
Now that you've extended the `Ruggeduino` class to create your `CustomisedRuggeduino` class,
183-
it's time to tell the `Robot` object about it using the `ruggeduino_set_handler_by_fwver` function:
184-
185-
~~~~~ python
186-
from sr.robot import *
187-
188-
# The class that you wrote in step 2
189-
class CustomisedRuggeduino(Ruggeduino):
190-
def bake_cake(self):
191-
with self.lock:
192-
self.command("c")
193-
194-
R = Robot.setup()
195-
196-
# Register the custom class with the Robot object
197-
R.ruggeduino_set_handler_by_fwver("SRcustom", CustomisedRuggeduino)
198-
199-
R.init()
200-
201-
R.wait_start()
202-
203-
# Now you can call your custom function!
204-
R.ruggeduinos[0].bake_cake()
205-
~~~~~
90+
The `cake_result` variable will contain any response from your firmware, if you sent one.
20691

20792
You're done! You can now use your custom cake-baking firmware!
20893

209-
210-
#### Multiple Ruggeduinos with Extended SR Firmwares
211-
212-
You may wish to use multiple Ruggeduinos with your robot, each supporting a different set of commands.
213-
There are two ways to go about this.
214-
215-
You can change the string "SRCustom" in your firmwares to be something different
216-
(but make sure you keep the colon that follows it!),
217-
and then change the string you pass to `ruggeduino_set_handler_by_fwver` to suit.
218-
For example, if you change it to be "CakeBaker" in one of your ruggeduinos,
219-
but leave it as "SRCustom" in the other, then your enumeration code would become:
220-
221-
~~~~~ python
222-
R.ruggeduino_set_handler_by_fwver("SRcustom", CustomisedRuggeduino)
223-
R.ruggeduino_set_handler_by_fwver("CakeBaker", CakeBakerRuggeduino)
224-
~~~~~
225-
226-
Alternatively, you can set the handling class using the ID of the Ruggeduino.
227-
The Ruggeduino IDs are written to the robot log when you run a program on your robot with your Ruggeduino connected.
228-
Instead of using `ruggeduino_set_handler_by_fwver`, you use `ruggeduino_set_handler_by_id`:
229-
230-
~~~~~ python
231-
R.ruggeduino_set_handler_by_id("752303138333517171B1", CustomisedRuggeduino)
232-
R.ruggeduino_set_handler_by_id("10231028301928310283", CakeBakerRuggeduino)
233-
~~~~~
234-
235-
You will then be able to access your ruggeduino using its ID like so:
236-
237-
~~~~~ python
238-
R.ruggeduinos["752303138333517171B1"]
239-
~~~~~
240-
94+
If you have multiple Ruggeduino running custom firmware, you can keep track of which one is which
95+
by using the serial numner.
24196

24297
[Completely custom firmware](#completely) {#completely}
24398
----------------------------
@@ -249,43 +104,30 @@ To configure a `Robot` object to ignore a Ruggeduino with custom firmware, you w
249104
The Ruggeduino ID is a 20 character string of mostly numbers, and is output in the robot log when you run a program on your robot with your
250105
Ruggeduino connected.
251106

252-
After calling `Robot.setup()`, you should call the `ruggeduino_ignore_id`
253-
method of the robot object, with the ID as an argument.
254107
You'll need the ID later, so it's best to save it into a variable:
255108

256109
~~~~~ python
257110
from sr.robot import *
258111

259112
RUGGEDUINO_ID = "752303138333517171B1" # Replace this with the actual ID
260113

261-
R = Robot.setup()
262-
263-
R.ruggeduino_ignore_id( RUGGEDUINO_ID )
264-
265-
R.init()
266-
267-
R.wait_start()
114+
R = Robot(ignored_ruggeduinos=["752303138333517171B1"])
268115

269116
# The rest of your code
270117
~~~~~
271118

272119
If you need to communicate with the Ruggeduino firmware, you will need its serial device path.
273-
This is accessible after the `R.init()` call through the list of Ruggeduinos:
274-
275-
~~~~~ python
276-
# ... Robot.setup() ... etc.
277120

278-
R.init()
121+
This is accessible from the `ignored_ruggeduinos` dictionary.
279122

280-
ruggeduino_device = R.ruggeduinos[RUGGEDUINO_ID].path
281-
282-
# Do your Ruggeduino initialisation here if you wish
283-
284-
R.wait_start()
123+
~~~~~ python
124+
ruggeduino_device = R.ignored_ruggeduinos[RUGGEDUINO_ID]
285125

286126
# The rest of your code
287127
~~~~~
288128

129+
The device path will look something like `/dev/ttyACM1`.
130+
289131
You may wish to use pyserial to communicate with the Ruggeduino, in which case you could open it like so:
290132

291133
~~~~~ python
@@ -294,12 +136,9 @@ from sr.robot import *
294136

295137
RUGGEDUINO_ID = "752303138333517171B1"
296138

297-
R = Robot.setup()
298-
R.ruggeduino_ignore_id( RUGGEDUINO_ID )
299-
R.init()
300-
R.wait_start()
139+
R = Robot(ignored_ruggeduinos=["752303138333517171B1"])
301140

302-
ser = serial.Serial( R.ruggeduinos[RUGGEDUINO_ID].path )
141+
ser = serial.Serial(R.ignored_ruggeduinos[RUGGEDUINO_ID])
303142

304143
~~~~~
305144

0 commit comments

Comments
 (0)