HSC2011/Building your own EduBuzzer: Unterschied zwischen den Versionen
Chrysn (Diskussion | Beiträge) (→The main board: page complete except for flashing, eeprom setting and base station) |
Daxim (Diskussion | Beiträge) (software development) |
||
Zeile 62: | Zeile 62: | ||
Align the holes in the board with the matching parts of the lower part and just screw it in somehow. | Align the holes in the board with the matching parts of the lower part and just screw it in somehow. | ||
=== software development === | |||
==== architectural overview ==== | |||
Each Edubuzzer app, e.g. '''Raise Your Hands''', is chiefly implemented in a | |||
single responsible JavaScript file, e.g. <tt>raise-your-hands.js</tt>. Each one can | |||
define a single callback, <tt>Edubuzzer.run_application</tt> which is called when | |||
the application is started. | |||
Inside <tt>Edubuzzer.run_application</tt> it may register other callbacks like | |||
<tt>Edubuzzer.updated_known_logins</tt> which is called whenever a client is added | |||
or removed, or <tt>Edubuzzer.display</tt> which is called in regular intervals. | |||
<tt>global.js</tt> runs a poor man's event loop and schedules all pollings to the | |||
server which result in callbacks of the active app registered being called. An | |||
app is activated by changing the URI <tt>#hash</tt>. The skeleton switches to an app | |||
by simply overwriting the <tt>display</tt> function. | |||
==== querying buzzers ==== | |||
<tt>/ygor</tt> is the base URI for the middleware endpoint. Send <tt>GET</tt> requests to | |||
certain named queries, e.g. <tt>?name=ls_accepted_login.sql</tt>. For the full list, | |||
see directory <tt>Ygor/sql/</tt> in the [https://github.com/Metalab/hsc2011/tree/master/software software repository]. It returns a JSON array of objects/hashes whose | |||
keys are described in the SQL file, e.g. for above: | |||
<code> | |||
[{"rowid":42,"src":"BUZZER-DEVICE-ID","dest":"MASTER-DEVICE-ID", | |||
"seqnum":23,"ibutton":"SOMETHING","since":"TIMESTAMP", | |||
"accepted":true,"ack":false}, … ] | |||
</code> | |||
Refer to the table schemas in <tt>Ygor/schema/</tt> for explicit key/row names. Rely | |||
on <tt>src</tt> for uniquely identifying a buzzer. | |||
The most important query is <tt>ls_events.sql</tt> because it deals with the device | |||
buttons. The first line in the file hints at the additional query parameters, | |||
in this case <tt>loginid</tt>, i.e. the full query string is | |||
<tt>?name=ls_events&loginid=ROWID</tt> where <tt>ROWID</tt> is a number received in earlier | |||
different queries. Extract the button status from the <tt>eventmask</tt> field. See | |||
<tt>docs/serialprotocol</tt> for the semantics. | |||
For debugging purposes the middleware exposes an echo interface at base URI | |||
<tt>/echo</tt>. The query string is ignored except for the parameter name | |||
<tt>Response-Body</tt>. Its value is a percent encoded JSON string which | |||
unsurprisingly is returned as response body. | |||
For example, you want to mock: | |||
<code> | |||
$.getJSON( | |||
Edubuzzer.middleware_endpoint+'?name=…', | |||
function (foo) { | |||
… | |||
} | |||
) | |||
</code> | |||
Add a [http://api.jquery.com/jQuery.getJSON/ second parameter to the <tt>getJSON</tt> call], thus: | |||
<code> | |||
$.getJSON( | |||
Edubuzzer.middleware_mock_endpoint+'?name=…', | |||
'Response-Body'+encodeURIComponent('[{"rowid":123}]') | |||
function (foo) { | |||
… | |||
} | |||
) | |||
</code> | |||
==== instruction list ==== | |||
* decide on an app name (e.g. <tt>exampleapp</tt>) | |||
* create a new JavaScript file with the name | |||
* implement the <tt>run_application</tt> function and the hooks you need | |||
** present the app UI in element <tt>#buzzers</tt> | |||
** keep internal data under the <tt>Edubuzzer.exampleapp</tt> namespace | |||
* add the app name/link in <tt>index.xhtml</tt> | |||
* register the app in <tt>global.js</tt> | |||
* add styles in <tt>edubuzzer.css</tt> | |||
=== Done === | === Done === |
Version vom 1. Mai 2011, 22:54 Uhr
< HSC2011
Requirements
In order to build an EduBuzzer, you'll need
a bunch of electronic parts you can obtain from your supplier of choice,
equipment for etching a two sided PCB (as an alternative, you can order it just as well -- we didn't etch ours),
a rapid prototyper (3D printer, e.g. a makerbot),
a programmer for AVR microcontrollers (any AVR microcontroller with a bootloader will do, especially an Arduino -- c.f. the Arduino ISP tutorial) with appropriate software, e.g. avrdude,
and a copy of the EduBuzzer software and hardware description from the project download page.
Hardware
The main board
For etching the main board, you'll find all required files in the hardware/gerber subdirectory of the repository, or you can directly use the Eagle files in hardware. For building an ergonomic buzzer, use the buzzer files.
As an alternative (to try it out with less effort), use the arduino_schield files -- with them, you need fewer components, and get an arduino shield you can plug onto an Arduino compatible device. If you are good at soldering and want to get going with what is present in a typical hackerspace (at least, in the metalab), you can produce the same circuit even on a prototyping shield.
Solder in all the components as described in the part list, starting with the big parts. We recommend to use sockets for both the ATMega328 and the RFM12B module, as they are prone to overheating from inexperienced soldering, and as there is no programming header exposed for the ATMega. (Updates can be flashed using a serial bootloader, but if you break something, things get tricky.) Other parts to take care of:
- R10 -- don't install it, it's for adjusting the compatibility behavior with respect to Arduino's DTR handling, and
- SW5 -- connect using about 5cm of cable, as the switch is installed in a dedicated slot in the case.
Checkpoint: You can try out the hardware immediately by flashing firmware/ioexample.hex onto an ATMega328 (works even with the ATMega328 built in in an Arduino -- just flash it as normal, take out the chip put it into the buzzer's socket). The device will:
- when the first button is pressed, blink through all LEDs,
- when the second button is pressed, make sounds while toggling through the LEDs,
- when the third button is pressed, fade the RGB LED around all colors,
- when the last button is pressed, send commands over radio,
- when an iButton is inserted, show a hash of its ID on the LEDs, and buzz six times.
When the IO-example is flashed on two devices, the second should respond to the radio commands and cycle through its own LEDs.
If you checked the functionality of the example, you can flash firmware/firmware.hex onto it. While you are at it, you can write the MAC addresses of the device and its configured base station directly to EEPROM in this step as well.
The enclosure
Print the enclosure as described in the enclosure directory in the repository.
You will get
- a top part,
- a bottom part,
- and an acryl part in that goes in between the others.
Assembling
Put the battery under the bridge in the lower part of the enclosure, the contacts go to the narrow side. You may need to remove artefacts from the production from rapid prototyping. The switch is put in the socket at the other side of the lower part and can be screwed tight. The toggling part of the switch will slightly protude from the surface.
Align the holes in the board with the matching parts of the lower part and just screw it in somehow.
software development
architectural overview
Each Edubuzzer app, e.g. Raise Your Hands, is chiefly implemented in a single responsible JavaScript file, e.g. raise-your-hands.js. Each one can define a single callback, Edubuzzer.run_application which is called when the application is started.
Inside Edubuzzer.run_application it may register other callbacks like Edubuzzer.updated_known_logins which is called whenever a client is added or removed, or Edubuzzer.display which is called in regular intervals.
global.js runs a poor man's event loop and schedules all pollings to the server which result in callbacks of the active app registered being called. An app is activated by changing the URI #hash. The skeleton switches to an app by simply overwriting the display function.
querying buzzers
/ygor is the base URI for the middleware endpoint. Send GET requests to certain named queries, e.g. ?name=ls_accepted_login.sql. For the full list, see directory Ygor/sql/ in the software repository. It returns a JSON array of objects/hashes whose keys are described in the SQL file, e.g. for above:
[{"rowid":42,"src":"BUZZER-DEVICE-ID","dest":"MASTER-DEVICE-ID",
"seqnum":23,"ibutton":"SOMETHING","since":"TIMESTAMP",
"accepted":true,"ack":false}, … ]
Refer to the table schemas in Ygor/schema/ for explicit key/row names. Rely on src for uniquely identifying a buzzer.
The most important query is ls_events.sql because it deals with the device buttons. The first line in the file hints at the additional query parameters, in this case loginid, i.e. the full query string is ?name=ls_events&loginid=ROWID where ROWID is a number received in earlier different queries. Extract the button status from the eventmask field. See docs/serialprotocol for the semantics.
For debugging purposes the middleware exposes an echo interface at base URI /echo. The query string is ignored except for the parameter name Response-Body. Its value is a percent encoded JSON string which unsurprisingly is returned as response body.
For example, you want to mock:
$.getJSON(
Edubuzzer.middleware_endpoint+'?name=…',
function (foo) {
…
}
)
Add a second parameter to the getJSON call, thus:
$.getJSON(
Edubuzzer.middleware_mock_endpoint+'?name=…',
'Response-Body'+encodeURIComponent('[{"rowid":123}]')
function (foo) {
…
}
)
instruction list
- decide on an app name (e.g. exampleapp)
- create a new JavaScript file with the name
- implement the run_application function and the hooks you need
- present the app UI in element #buzzers
- keep internal data under the Edubuzzer.exampleapp namespace
- add the app name/link in index.xhtml
- register the app in global.js
- add styles in edubuzzer.css