Om in mijn robots de communicatie tussen de controllers te versimpelen heb ik een bussysteem ontworpen dat ik SubSumption Architecture Bus heb genoemd, oftewel kortweg de SSA-Bus. Dit systeem bestaat uit één master en maximaal 8 slaves.
De bus wordt gecontroleerd door de SSA Master. Deze bus bevat behalve de voeding de communicatielijnen van SPI, TWI (I²C) en serieel. Verder een centrale RESET pin bevat deze bus een algemene interrupt lijn HALT voor een noodstop. Iedere controller kan deze lijn laag trekken en veroorzaakt daarmee onder meer een onmiddelijke noodstop. Verder heeft iedere slave zijn SPISCK en zijn SS pin aangesloten aan een eigen I/O pin op de SSA master. Daardoor kan er worden geadresseerd en worden gecommuniceerd. Afbeelding 1 geeft een overzicht van de aansluitingen. Alle overige lijnen van de bus worden gebruikt om de aangesloten controllers (slots) te adresseren.
I²C heeft 2 pull-up weerstanden nodig op de bus. Ze zijn op deze print gemonteerd. Volgens Atmel AVR315: Using the TWI module as I2C master zijn deze weerstanden typically 4,7k.
Het frontje is 2 cm breed en bevat van boven naar beneden: de aan/uit schakelaar, de aansluiting van het chassis, de centrale reset button en een controle LED voor de 12Vdc spanning (groen).
Prints die zich op de SSA-Bus willen aansluiten moeten aan verschillende ontwerpeisen voldoen.
Mr Blue SSA-bus
Opbouw enkelpolig-om
Verder bevat de opbouw van mr Blue aan de zijkant nog een enkelpolig-om schakelaar. Deze schakelaar verbindt SSA-Bus pin 3 (voeding SSA-Bus, rood) met:
OF de externe 5Vdc aansluiting op de opbouw en biedt deze ook aan via SSA-Bus pin 3 als voeding voor de onderbouw. In bepaalde testcases kan het handig zijn om door middel van dip-switches de onderbouw zich te laten voeden door de bovenbouw.
OF de gestabiliseerde 5Vdc voeding vanaf de 9Vdc batterij op het chassis via de SSA-Bus pin 5 (bruin). In deze stand bepaalt de Cybot Aan/uit schakelaar of de bovenbouw wordt gevoed. Indien de Cybot Aan/uit schakelaar op UIT staat, dan krijgt de bovenbouw geen voeding. Ook SSA-Bus pin 3 (rood) heeft geen spanning. De motoren krijgen niet hun 6Vdc voeding. Daarentegen, als de Cybot Aan/uit schakelaar op AAN staat dan worden de bovenbouw en SSA-Bus pin 3 (rood) gevoed vanuit de batterijen die worden aangeboden via SSA-Bus pin 5 (bruin). Het 6Vdc gedeelte van de motoren heeft in deze stand continu spanning.
Cybot Aan / uit |
Boven switch Rechts / links |
Dipswitch |
Voeding 6Vdc motoren |
Voeding Boven |
Voeding Onder |
Aan |
Rechts |
1:Uit 2:Uit |
6 Vdc batterij-pack |
Externe voeding |
Afgesloten |
1:Aan 2:Uit |
6Vdc batterij-pack |
Externe voeding |
Externe voedingsaansluiting |
|
1:Uit 2:Aan |
6Vdc batterij-pack |
Externe voeding |
9Vdc batterij |
1:Aan 2:Aan |
6Vdc batterij-pack |
Beiden, paralel geschakeld |
Beiden, paralel geschakeld |
Links |
1:Uit 2:Uit |
6Vdc batterij-pack |
9Vdc batterij |
Afgesloten |
|
1:Aan 2:uit |
6Vdc batterij-pack |
9Vdc batterij |
9Vdc batterij |
|
1:Uit 2:Aan |
6Vdc batterij-pack |
9Vdc batterij |
9Vdc batterij |
|
1:Aan 2:Aan |
6Vdc batterij-pack |
Beiden, paralel geschakeld |
Beiden, paralel geschakeld |
Uit |
Rechts |
1:Uit 2:Uit |
Afgesloten |
Externe voedings |
Afgesloten |
1:Aan 2:Uit |
Afgesloten |
Externe voeding |
Externe voedingsaansluiting |
1:Uit 2:Aan |
Afgesloten |
Externe voeding |
Afgesloten |
1:Aan 2:Aan |
Afgesloten |
Externe voeding |
Externe voedingsaansluiting |
Links |
1:Uit 2:Uit |
Afgesloten |
Afgesloten |
Afgesloten |
1:Aan 2:Uit |
Afgesloten |
Afgesloten |
Afgesloten |
1:Uit 2:Aan |
Afgesloten |
Afgesloten |
Afgesloten |
1:Aan 2:Aan |
Afgesloten |
Afgesloten |
Afgesloten |
Kennelijk mag DIP-switch 1 altijd aanstaan en DIP-switch 2 altijd uit indien de SSA-Bus is aangesloten. Indien de SSA-Bus niet is aangesloten, dan
-
Cybot Aan/uit schakelaar: AAN
De motoren (oftwel het 6Vdc batterij-pack) kunnen enkel door deze schakelaar worden geschakeld. In welke stand de Opbouw enkelpolig-om schakelaar ook staat, de motoren worden altijd gevoed. De motoren kunnen zich uitsluitend vanuit het batterij-pack voeden, maar dat is geen probleem want in de praktijk wilt u op dat moment toch dat uw systeem mobiel is. De electronica van de onderbouw wordt gevoed door de gestabiliseerde 5Vdc voeding zoals die wordt aangeboden op de SSA-Bus pin 5 (bruin) door de 9Vdc batterij. Ook de bovenbouw kan zich nu via deze pin voeden.
Let op: het AAN zetten van deze schakelaar leidt dus altijd tot verbruik in de batterijen. Enkel het UIT zetten van deze schakelaar voorkomt batterij verlies.
-
Opbouw enkelpolig om schakelaar: RECHTS
In dit geval wordt de bovenbouw gevoed via de SSA-Bus aansluiting. Dit is de batterijvoeding van de 9Vdc batterij, die gestabiliseerd als 5Vdc wordt aangeboden door het chassis. De onderbouw wordt gevoed vanuit de batterijen. Ook het 6Vdc systeem met de voeding van de motoren staat aan. De robot is dus mobiel.
-
Opbouw enkelpolig om schakelaar: LINKS
Dit is de externe voeding zoals deze is aangesloten via de banaanstekkers. Aangezien de Cybot Aan/uit schakelaar op AAN staat geeft u te kennen dat u wilt dat uw systeem mobiel funcioneert. In dat geval zou er dus logischerwijze niets op de bananen-stekkers van de externe voeding aangesloten zijn. Dat betekent dat de bovenbouw uitstaat, terwijl de onderbouw gewoon door zichzelf gevoed wordt. Mocht er nu onverhoopt toch een externe voeding zijn aangesloten op de bananen-stekkers dan betekent deze stand dat de bovenbouw wordt gevoed door de externe voeding. De onderbouw wordt in deze situatie nog steeds gevoed door de batterijen. Deze situatie kan zich voordoen gedurende sommige testen.
-
Cybot Aan/uit schakelaar: UIT
De motoren (oftwel het 6Vdc batterij-pack) kunnen enkel door deze schakelaar worden geschakeld. In welke stand de Opbouw enkelpolig-om schakelaar ook staat, de motoren zullen niet functioneren. Deze kunnen zich uitsluitend vanuit het batterij-pack voeden, maar dat is geen probleem want in de praktijk wilt u dan toch dat uw systeem mobiel is.
-
Opbouw enkelpolig-om schakelaar: RECHTS
Dit is de batterijvoeding zoals deze wordt aangeboden door het chassis. Aangezien de Cybot Aan/uit schakelaar op UIT staat geeft u te kennen dat u wilt dat u systeem niet mobiel acteert. Om batterijen te sparen krijgen zowel het chassis alsook de opbouw geen voeding doordat de batterijen beiden afgeschakeld zijn. In deze situatie betekent deze stand dat zowel de bovenbouw uitstaan. De bovenbouw staat dus uitgeschakeld, ook al is er een externe voeding aangesloten. Ook de ondebouw kan niet worden gevoed via SSA-Bus pin 3 (rood).
-
Opbouw enkelpolig-om schakelaar: LINKS
De bovenbouw voedt zich in deze situatie met de externe voeding zoals deze is aangesloten via de banaanstekkers. Aangezien de Cybot Aan/uit schakelaar op UIT staat geeft u te kennen dat u wilt dat u systeem niet mobiel acteert. Om batterijen te sparen krijgen zowel het chassis alsook de opbouw geen voeding doordat de batterijen beide afgeschakeld zijn. Nu zijn er 2 mogelijkheden:
-
Externe voeding wel aangesloten
In het geval dat de robot statisch (zonder te hoeven bewegen) kan worden ontwikkeld dan zal dit ook gebeuren. Dit om batterijen en veel lopen door de kamer te besparen. In dat geval is het waarschijnlijk dat er een externe voeding is aangesloten op de bovenbouw bananen-stekkers. Deze externe voeding wordt in deze situatie gebruikt om de bovenbouw te voeden. Bovendien wordt de extern verkregen voedingsspanning op de SSA-Bus pin 3 (rood) doorgegeven. De print op het chassis kan zich nu voeden via deze leiding. De motoren worden niet gevoed. Dit is dus erg handig als er software getest moet worden.
-
Externe voeding niet aangesloten
Omdat het chassis ook zonder opbouw zelfstandig moet kunnen functioneren, bevat de basisprint op het chassis een aantal DIP-switches. Als deze omhoog staan, dan staan ze uit. De nummers van de switches staan onder de schakelaars. Indien mr Blue zonder opbouw moet functioneren, dan staat nummer 10 aan. Indien mr Blue met opbouw moet functioneren, dan moet deze schakelaar uit staan. Deze schakelaar koppelt de gestabiliseerde batterij voeding direct aan he voeding van de basisprint.
Opbouw Reset
Dit is een algemene drukschakelaar, maakcontact, waarop alle controllers worden aangesloten. Indien de reset knop wordt ingedrukt, dan wordt de reset pin van de controllers met de aarde verbonden. Zodra dit langer gebeurt dan voor 1 clock cylcle dan wordt de controller gereset. Aangezien de reset aansluiting op AVR controllers ook wordt gebruikt tijdens het programmeren, moeten deze leidingen met een diode en weerstand van elkaar ontkoppeld worden. Overigens bevat de basisprint op het chassis ook een reset schakelaar (met hetzelfde resultaat, omdat dit board ook zonder opbouw moet kunnen functioneren.
Opbouw bananenstekkers
Op deze rode (5Vdc) en zwarte (Aarde) bananenstekkers kan een externe voeding op de opbouw worden aangesloten.
//This is an include, so no parsing needed
$qry2 = ("SELECT onderdelen.*,
soortonderdeel.id
FROM onderdelen
JOIN soortonderdeel ON onderdelen.idsrtodd = soortonderdeel.id
WHERE onderdelen.partid = $idpart
;");
$result2 = pg_query($con1, $qry2);
$row4 = pg_fetch_array($result2); //Make the fields accesible
foreach( $row4 AS $key => $val ){
$$key = stripslashes( $val );
}
$jaar = substr($changeddate,0,4);
$maand = substr($changeddate,5,2);
$dag = substr($changeddate,8,2);
$lastupdate = ("$jaar $maand $dag");
$prtsrttxt = get_txt($con1, 26, 1, $idsrtodd);
$jaar = substr($createddate,0,4);
$maand = substr($createddate,5,2);
$dag = substr($createddate,8,2);
$create_stamp = ("$dag $maand $jaar");
//GENERAL INFO FOR EVERY USER **************************************************
echo (" ");
echo (""); //Header
$tmp = get_txt($con1, 9, $koekje[2], 3923); //Fieldname at screen
if ($koekje[3]=="1") { //If this user wants to translate then
echo ("$tmp"); //If desired
}else{ echo ("$tmp"); } //Else just show if no need to translate
if ($koekje[0]>0 and $koekje[3]>0){ //User is logged in and translates
echo (" (edit)");
}
echo ("Algemene informatie test | ");
if ($codetext) { //Code like KY-026 or NA-41
echo ("");
$tmp = get_txt($con1, 9, $koekje[2], 3739); //Fieldname at screen
if ($koekje[3]=="1") { //If this user wants to translate then
echo ("$tmp"); //Class for colour
}else{ //So you are not allowed to translate
echo $tmp; //Show screenname of this field in user language
} //End of If you want to translate this fieldname at screen
echo ("  | ");
if ($codelink) {
echo ("$codetext");
}else{
echo ("$codetext");
} //End of if ($pinoutlink)
echo (" | ");
} //End of if ($codetext)
$tmp = get_txt($con1, 9, $koekje[2], 3741); //Fieldname at screen
if ($prijseurinclbtw > 0){ //Show price indication
$prijs_formatted = number_format($prijseurinclbtw / 100, 2, ',', '.');
echo ("$tmp   | ");
echo ("");
if ($urlprijs){
echo ("€  $prijs_formatted");
}else{
echo ("€  $prijs_formatted");
} //End of if ($urlprijs > "")
echo (" | ");
} //End of if ($prijseurinclbtw > 0)
if ($sketchtext) { //Link to OWN SOFTWARE
$tmp = get_txt($con1, 9, $koekje[2], 3738); //Fieldname at screen
echo ("$tmp   | ");
if ($sketchlink) {
echo ("$sketchtext");
}else{
echo ("$sketchtext");
} //End of if ($sketchlink)
echo (" | ");
} //End of if ($sketchtext)
$tmp = get_txt($con1, 9, $koekje[2], 3744); //Fieldname at screen
if ($pinouttext) { //Pinout
echo ("$tmp   | ");
if ($pinoutlink) {
echo ("$pinouttext");
}else{
echo ("$pinouttext");
} //End of if ($pinoutlink)
echo (" | ");
}
$tmp = get_txt($con1, 9, 1, 3735); //Fieldname at screen
$tmp2 = get_txt($con1, 26, 1, $row4[16]); //Group name in its language
echo ("$tmp   | "); //MENU GROUP
echo ("");
echo ("$tmp2 | ");
if ($koekje[0]>0 and $koekje[3]>0){ //User is logged in and translates
$tmp = get_txt($con1, 9, $koekje[2], 3918); //Fieldname at screen LANGUAGE
if ($row4[26] == 1) {$imgname = "nederland.png";}
if ($row4[26] == 2) {$imgname = "deutschland.png";}
if ($row4[26] == 3) {$imgname = "uk.png";}
if ($row4[26] == 4) {$imgname = "france.png";}
echo ("$tmp | ");
echo ("");
echo (" | ");
$tmp = get_txt($con1, 9, $row4[27], 3919); //Fieldname at screen
$statuskey = get_status_key($con1, $status);
$tmp2 = get_txt($con1, 61, $koekje[2], $statuskey); //Fieldname at screen
echo ("$tmp   | "); //STATUS
echo ("$status $tmp2 | ");
}
$tmp = get_txt($con1, 9, 1, 3966); //Fieldname at screen
echo ("$tmp   | "); //LAST CHANGED
$tmp = substr($changeddate, 0, 10);
echo ("$tmp | ");
echo (" ");
return;
////////////////////////////////////////////////////////////////////////////////
function get_status_key($con, $num){
$qry = ("SELECT id FROM status WHERE nr = $num ;");
$result = pg_query($con, $qry);
$row = pg_fetch_array($result);
return ("$row[0]");
}
// LIST ALL SOFTWARE THAT WILL RUN OM THIS PART *****************************
// INCLUDED IN ALL ROBOTS TO CHECK THEIR DIRECTORY
$qry2=("SELECT tblsystext.txtname
, software.urlmain
, software.sftname
, software.sftid
, software.controller
FROM software
LEFT JOIN tblsystext ON software.controller = tblsystext.recordid
WHERE position(' $idpart ' in software.prtlst) > 0
AND software.rstid = 2
AND tblsystext.lanid = $koekje[2]
AND tblsystext.txlid = 19
ORDER BY sftname ASC
, controller ASC
;");
$result = pg_query($con1, $qry2);
if (pg_num_rows($result)>0) { //Only if at least 1 program exists
echo (' ');
echo (""); //Header
$tmp = get_txt($con1, 9, $koekje[2], 3922); //Fieldname at screen
if ($koekje[3]=="1") { //If this user wants to translate then
echo ("$tmp"); //If desired
}else{ echo ("$tmp"); } //Else just show if no need to translate
echo (" |
---|
");
while($col = pg_fetch_array($result)){
$col[0] = ("$col[0]");
echo (" ");
echo ("$col[2]   | ");
echo ("$col[0] | ");
if ($koekje[0] > 0 and $koekje[3]>0){ //User is logged in and translates
echo ("");
echo ("(Edit) | ");
}
echo (' ');
}
echo (' ');
}
?>
// LIST ALL ROBOTS THAT INCLUDE THIS PART ***********************************
// $idpart
// INCLUDED IN ALL ROBOTS TO CHECK THEIR DIRECTORY
$qry_bpp=("SELECT farmbotversie.id
, farmbotversie.part_list
, tblsystext.txtname
FROM farmbotversie
LEFT JOIN tblsystext ON farmbotversie.id = tblsystext.recordid
WHERE tblsystext.txlid = 27
AND tblsystext.lanid = $koekje[2]
ORDER BY tblsystext.txtname ASC
;");
$result_bpp = pg_query($con1, $qry_bpp);
$header = 0;
while($colbpp = pg_fetch_array($result_bpp)){ //Only if at least 1 robot exists
if(substr_count($colbpp[1], " $idpart ") > 0){
if ($header == 0) {
echo ("");
echo (""); //Header
$tmp = get_txt($con1, 9, $koekje[2], 3879); //Fieldname at screen
if ($koekje[3]=="1") { //If this user wants to translate then
echo ("$tmp"); //If desired
}else{ echo ("$tmp"); } //Else just show if no need to translate
echo (" | ");
$header++;
} //End of if ($header == 0)
echo ("");
echo ("$colbpp[2]");
//Show software van deze bot
$qry=("SELECT software_basedir
FROM farmbotversie
WHERE id = $colbpp[0];");
$result = pg_query($con1, $qry);
$col = pg_fetch_array ($result ,0);
$dir1 = "/var/www/html/robotigs/software/$col[0]";
$arr1 = glob($dir1, GLOB_ONLYDIR);
if (isset($arr1[0])){
$folder = $arr1[0];
$countertmp = 0;
echo ("");
foreach (scandir($folder, 1) as $filename) {
if ($filename<>"." AND $filename <>".."){
if ($countertmp == 0){
$countertmp++;
} //End of if ($countertmp == 0)
$tmp = "/";
$dir = substr($folder, 14) ."/";
$link = $tmp .$dir .$filename;
$showname = substr($filename, 0 ,-4);
echo ("- ");
echo "$showname";
echo ("
");
} //End of if ($filename<>"." AND $filename <>".."){
} //End of foreach (scandir($folder, 1) as $filename)
echo ("");
} //End of if (isset($arr1[0]))
echo (" | ");
}
}
if ($header > 0){
echo (" ");
}
?>
Warning: include(/var/www/html/robotigs/includes/wishlistperpart.php): Failed to open stream: No such file or directory in /var/www/html/robotigs/includes/parts_header.php on line 128
Warning: include(): Failed opening '/var/www/html/robotigs/includes/wishlistperpart.php' for inclusion (include_path='.:/usr/share/php') in /var/www/html/robotigs/includes/parts_header.php on line 128
| //Location:/robotigs/includes/ picts_show.php
// Requieres: $pict_list and several picture handling javascript routines
//*** FROM HERE ON THE PICTURE CORNER STARTS -----------------------------------
if ($pict_list){ //There are 1 or more pictures to be printed
echo ("");
$counter = 0;
$aantal = str_word_count($pict_list, 0, "0123456789");
$lijst = str_word_count($pict_list, 1, "0123456789");
while($counter < $aantal){
$pictkey = $lijst[$counter];
$qryy1 = ("SELECT *
FROM illustrations
WHERE ill_id = $pictkey
;");
$resulty1 = pg_query($con1, $qryy1);
while($row = pg_fetch_array($resulty1)){ //Fields accesible by their name
foreach( $row AS $key => $val ){
$$key = stripslashes( $val );
}
}
$image = ("/robotigs/documentatie/plaatjes/$ill_name");
$pictfull = str_replace('_small', '', $image); //Pictfull=biggest version
$alt = ("Just wait till your 57....");
$txtname = get_txt($con1, 18, $koekje[2], $ill_id); //Robot illustrations subtitles
echo ("");
echo (' ');
$nummer = $counter + 1;
$txtAfb = get_txt($con1, 9, $koekje[2], 3865); //Pic Afb
if ($koekje[0]>0 and $koekje[3]>0){ //User is logged in and translates
echo ("$txtAfb $nummer: ");
echo ("$txtname");
echo (" ");
echo ("Ontkoppelen ");
if ($counter==0){
echo ("Up ");
}else{
echo ("Up ");
}
if ($nummer == $aantal){
echo ("Down");
}else{
echo ("Down");
}
}else{ //Else of if Meaning the current useer is logged in
echo ("$txtAfb $nummer: $txtname");
}
echo (''); //End of this picture
$counter++; //Prepair for next picture
}
echo (' | '); //All pictures are printed
} //End of if there are 1 or more pictures to be printed ----------------------
?>