BrickPi3: Quick Guide (mit C/C++ & "stackable" Shields)

Atmel, PIC, VEX, Fischertechnik

Moderator: Moderatoren

Benutzeravatar
HaWe
Administrator
Administrator
Beiträge: 5399
Registriert: 11. Jan 2006 21:01
Wohnort: ein kleiner Planet in der Nähe von Beteigeuze

BrickPi3: Quick Guide (mit C/C++ & "stackable" Shields)

Beitragvon HaWe » 16. Apr 2017 09:04

hallo,
auf meine Anfrage hin hat Dexter Industries für deren BrickPi3 jetzt auch begonnen, die ersten C/C++ API libs zur Verfügung zu stellen und außerdem auch die Firmware der BrickPi3 Shields zu überarbeiten, sodass sie jetzt "stackable = stapelbar" sind, d.h., man kann mehrere davon aufeinanderstecken und hat dann ein Vielfaches der jew. IOs.

BrickPi3-board-standing-front-1.jpg
BrickPi3-Base-Kit-battery-1.jpg


Man kann je Shield je 4 Lego-Sensoren (NXT, EV3) und 4 Lego-Motoren anschließen, z.B. die NXT Ultraschall- und die EV3 IR-Sensoren, sie lassen sich mit einfacher C/C++ Syntax programmieren (nicht ganz so einfach wie NXC, aber annähernd), und wenn man Geany als IDE direkt auf dem Raspi verwendet, muss man sich auch nicht mit ssh und puTTY oder mit Crosscompilern wie Eclipse rumschlagen:
Einfach HDMI Bildschirm an den Pi anschließen (5", 7", 10", 15", 24", was man grade halt da hat, ggf. auch Touchscreens, es skaliert sich automatisch) und eine Maus und ein keyboard (auch wireless), und man kann sofort loslegen.
BrickPi3 ist per SPI über die GPIO Steckerleiste mit dem Pi verbunden, ist stapelbar (ich meine mich zu erinnern: mindestens 8 Stück) und man hat so ohne weiteres 32 Lego-Sensoren und 32 Lego-Motoren zum Ansteuern (ggf sogar mehr), und das mit 1 einzigen Raspi.
Außerdem hat jedes Shield je 1 Grove Stecker für i2c-Sensoren, von denen man über 100 Stück einfach zusätzlich aneinanderhängen kann (wie bei i2c üblich).
Daneben sind die Raspi i2c- und UART ports und die meisten normalen digitalen GPIOS unbenutzt und weiter frei verfügbar, und man kann also jede Menge Raspi-Standard-Sensoren (Taster, Multiplexer, i2c-Sensoren etc.pp.) wie bei einem ganz normalen Raspi zusätzlich weiter verwenden, es können sogar noch weitere Bus-Ports wie 1-Wire, USB, und sogar der versteckte i2c-0 Bus genutzt werden.
Für Python-Fans etc. sind Raspi und BrickPi3 Shields außer mit C übrigens auch per Python, Scratch u.v.m. programmierbar.

Kurzer Einblick in die C++ API

Hier sind die ersten Links:

https://github.com/DexterInd/BrickPi3/t ... Software/C

ein Beispiel, um die Shield IDs auszulesen und zu initialisieren (Stand 15.4.2017):
https://github.com/DexterInd/BrickPi3/b ... .c#L40-L41

Code: Alles auswählen

/*
 *  https://www.dexterindustries.com/BrickPi/
 *  https://github.com/DexterInd/BrickPi3
 *
 *  Copyright (c) 2017 Dexter Industries
 *  Released under the MIT license (http://choosealicense.com/licenses/mit/).
 *  For more information, see https://github.com/DexterInd/BrickPi3/blob/master/LICENSE.md
 *
 *  This code is an example for reading BrickPi3 information
 *
 *  Results: Print information about the attached BrickPi3.
 *
 *  Example compile command:
 *    g++ -o program "info.c"
 *  Example run command:
 *    sudo ./program
 *
 */

#include "BrickPi3.cpp" // for BrickPi3
#include <stdio.h>      // for printf

BrickPi3 BP; // Create a BrickPi3 instance with the default address of 1
//BrickPi3 BP_7(7); // Create a BrickPi3 instance with address 7

int main(){
  //BrickPi3_set_address(1, ""); // set BrickPi3 with any id to the default address of 1
  //BrickPi3_set_address(7, "192A0F96514D4D5438202020FF080C23"); // set BrickPi3 with id 192A0F96514D4D5438202020FF080C23 to address 7
 
  BP.detect(); // Make sure that the BrickPi3 is communicating and that the firmware is compatible with the drivers.
 
  char string[33]; // Room for the 32-character serial number string plus the NULL terminator.
 
  BP.get_manufacturer(string);
  printf("Manufacturer    : %s\n", string);
 
  BP.get_board(string);
  printf("Board           : %s\n", string);
 
  BP.get_id(string);
  printf("Serial Number   : %s\n", string);
 
  BP.get_version_hardware(string);
  printf("Hardware version: %s\n", string);
 
  BP.get_version_firmware(string);
  printf("Firmware version: %s\n", string);
 
  printf("Battery voltage : %.3f\n", BP.get_voltage_battery());
  printf("9v voltage      : %.3f\n", BP.get_voltage_9v());
  printf("5v voltage      : %.3f\n", BP.get_voltage_5v());
  printf("3.3v voltage    : %.3f\n", BP.get_voltage_3v3());
}




Weitere Beispiele im oben verlinkten Github "Examples" Ordner

Benutzeravatar
HaWe
Administrator
Administrator
Beiträge: 5399
Registriert: 11. Jan 2006 21:01
Wohnort: ein kleiner Planet in der Nähe von Beteigeuze

Re: BrickPi3: Quick Guide (mit C/C++ & "stackable" Shields)

Beitragvon HaWe » 27. Apr 2017 11:07

Inhalt des Basis Kits:

(Bezugsquelle: Generation Robots, Frankreich, ca. 130 EUR inkl. Versand;
https://www.generationrobots.com/de/402 ... &results=7

momentan noch keine anderen Händler für Deutschland gefunden!)

brickPi3_0.jpg


brickPi3-1.jpg


( allerdings keine Beschreibung dabei! )

Benutzeravatar
HaWe
Administrator
Administrator
Beiträge: 5399
Registriert: 11. Jan 2006 21:01
Wohnort: ein kleiner Planet in der Nähe von Beteigeuze

Re: BrickPi3: Quick Guide (mit C/C++ & "stackable" Shields)

Beitragvon HaWe » 27. Apr 2017 12:33

Aufbau-Anleitung:

https://www.dexterindustries.com/BrickP ... g-started/
https://www.dexterindustries.com/BrickP ... ed/basics/



Montieren auf Standard-RaspberryPi- Abstandhalter: leider nicht möglich !

Entgegen Aussage von Dexter Ind. ist es nicht möglich, die BrickPi3 Shields mit 4 normalen Abstandshaltern zu befestigen -
es sind nur 2 Löcher für die Befestigung vorhanden, keine 4 wie eigentlich erforderlich, denn die restlichen 2, die nötig wären, sind mit Lego-Plugs verbaut.
17mm wie angegeben gingen eh nicht, weil der stacking header vom BrickPi3 Shield nur 14mm hoch ist, aber das ist natürlich nur das allerkleinste Problem: Das Problem ist, dass keine 4 Befestigungsbolzen möglich sind. sondern nur 2, dadurch wird die Montage extrem wackelig, speziell bei mehreren aufeinandergesteckten Shields oder HATs:

Zum anderen hat der BrickPi3 nur 26 Pins (wie der alte Raspi B), nicht 40 wie der neuere B+ und 2+3. Oben drauf lassen sich demnach überhaupt keine 40er HATs mehr draufsetzen....

BrickPi3-2.jpg


BrickPi3-3.jpg

Benutzeravatar
HaWe
Administrator
Administrator
Beiträge: 5399
Registriert: 11. Jan 2006 21:01
Wohnort: ein kleiner Planet in der Nähe von Beteigeuze

Re: BrickPi3: Quick Guide (mit C/C++ & "stackable" Shields)

Beitragvon HaWe » 27. Apr 2017 14:07

Allgemeine Links für Anfänger
(nicht spezifisch für C Programmierer):


https://www.dexterindustries.com/BrickP ... g-started/

Assemble The Case
The SD Card
Powering Up
Using the Raspberry Pi
Controlling the BrickPi
Attaching LEGO
Programming Your Robot



Installation von Raspbian:
Anm.:
BrickPi3 läuft mit den Standard-Raspbian SD Cards, wie sie z.B. automatisch von NOOBS erstellt und installiert werden.
Ich empfehle 16GB oder 32GB SD cards, möglichst hohe Datenübertragungsrate.


NOOBS-Link zur Installation:
https://www.raspberrypi.org/downloads/noobs/

Wichtig:
Nach jeder Neu-Installation und vor jeder neuen Zusatzinstallation immer obligatorisch erst einmal:

Code: Alles auswählen

sudo apt-get update
sudo apt-get upgrade
#dann
sudo reboot now
#dann
sudo apt-get autoremove


Installation der BrickPi3-Driver, C++ API Files und der Code Examples:
https://github.com/DexterInd/BrickPi3/b ... /README.md

Installation

On Raspbian for Robots, run DI Software Update to install or update - this is a more time-consuming option than the alternative instructions seen in the following section.
Quick Install

In order to quick install the BrickPi3 repository, open up a terminal and type the following command:

Code: Alles auswählen

  sudo curl -kL dexterindustries.com/update_brickpi3 | bash 


The same command can be used for updating the BrickPi3 to the latest version.

When you install the BrickPi3 software, the C++ drivers and examples are included
(they get installed in the directory /home/pi/Dexter/BrickPi3/Software/C).
For compiling, see the example compile command in the C examples.



Verbindungstest (Hardware/Firmware/Driver):

Zum Verbindungstest kann dieses Python-Programm verwendet werden:

Code: Alles auswählen

python3 /home/pi/Dexter/BrickPi3/Software/Python/Examples/Test_Connected.py

Achtung: Es gibt auch einen Fehler aus, wenn nur die Firmware Version zu alt ist, auch wenn sonst alles ok sein sollte.


Check / Update Firmware:

To check the firmware version, you can either run the python example "Read_Info.py" or you can compile and run the C program "info.c".

You can update the firmware as described here:
https://github.com/DexterInd/BrickPi3/b ... /README.md

Code: Alles auswählen

python3 /home/pi/Dexter/BrickPi3/Software/Python/Examples/Read_Info.py

bei mir war es ver 1.0.1, verlangt wird 1.4.x, daher:

Code: Alles auswählen

sudo bash /home/pi/Dexter/BrickPi3/Firmware/brickpi3samd_flash_firmware.sh




spätere Driver- und C++ Library-Updates:

Code: Alles auswählen

sudo rm -rf /home/pi/Dexter/BrickPi3
#dann wie oben
sudo git clone http://www.github.com/DexterInd/BrickPi3.git /home/pi/Dexter/BrickPi3
sudo bash /home/pi/Dexter/BrickPi3/Install/install.sh
sudo reboot




Trouble Shooting:

https://www.dexterindustries.com/BrickP ... -brickpi3/

mattallen37
Weniger als 15 Beiträge
Weniger als 15 Beiträge
Beiträge: 14
Registriert: 23. Jun 2011 00:07

Re: BrickPi3: Quick Guide (mit C/C++ & "stackable" Shields)

Beitragvon mattallen37 » 27. Apr 2017 17:18

Deutsch: Wie ich in der Dexter Industries Foren zum Stapeln erwähnt habe, 17mm oder 18mm Pfosten sollten gut funktionieren, wenn Sie direkt an eine Raspberry-Pi anschließen, aber vielleicht nicht, wenn Sie eine Verbindung zu einem anderen Brett herstellen. Es gibt nur zwei Befestigungslöcher, denn bei allen Motor- und Sensoranschlüssen gibt es keinen Platz für vier, und in der Standardkonfiguration (mit dem Acrylgehäuse) werden die Montagelöcher nicht einmal benutzt.

English: As I mentioned in the Dexter Industries forums regarding stacking, 17mm or 18mm posts should work fine if you are connecting directly to a Raspberry Pi, but maybe not if you are connecting to a different board. There are only two mounting holes because with all the motor and sensor ports, there's not room for four, and in the standard configuration (using the acrylic case) the mounting holes aren't even used.
Deutsch: Bitte vergib mir meine falsche Deutsch, ich bin mit Google für alles zu übersetzen.
English: Please forgive my improper German, I am using google translate for everything.

Matt

Benutzeravatar
HaWe
Administrator
Administrator
Beiträge: 5399
Registriert: 11. Jan 2006 21:01
Wohnort: ein kleiner Planet in der Nähe von Beteigeuze

Re: BrickPi3: Quick Guide (mit C/C++ & "stackable" Shields)

Beitragvon HaWe » 27. Apr 2017 18:23

yes, thank you for your clarification!
But as stated already above:
the main issue is that there are just 2 mounting holes, not 4 as actually required.
Gruß,
HaWe
±·≠≈²³αβγδε∂ζλμνπξφωΔΦ≡ΠΣΨΩ∫√∀∃∈∉∧∨¬⊂⊄∩∪∅∞®
NXT NXC SCHACHROBOTER: https://www.youtube.com/watch?v=Cv-yzuebC7E

Benutzeravatar
HaWe
Administrator
Administrator
Beiträge: 5399
Registriert: 11. Jan 2006 21:01
Wohnort: ein kleiner Planet in der Nähe von Beteigeuze

Re: BrickPi3: Quick Guide (mit C/C++ & "stackable" Shields)

Beitragvon HaWe » 28. Apr 2017 09:46

Erster Compile-/Build-Test mit Geany:

Anm.:
Geany ist automatisch bei Raspbian Jessie bereits mit installiert, ebenso der komplette C-Compiler gcc (g++)
Geany ist im GUI Desktop-Menü unter "Entwicklung" bereits als Shortcut hinterlegt (genau wie Python 2+3 und Scratch) und lässt sich von dort auch als zusätzlicher Shortcut auf dem Desktop ablegen.


Programm info.c in Geany geladen/geöffnet (Code siehe im TO Post)

Geany Einstellungen (Preferences) für compile und build:
keine besonderen zusätzlichen Flags nötig!

(aus Bequemlichkeitsgründen habe ich die Compile-Flags aus den Build-Flags übernommen, nur mit -c statt -o)

Code: Alles auswählen

# Compile:
g++ -Wall -c "%e" "%f"

# Build:
g++ -Wall -o "%e" "%f"

# Make:
make %e.o

# Ausführen:
sudo "./%e"


Ab jetzt kann man ganz bequem mit Funktionstasten als short-cuts arbeiten:
F8 (compile)
F9 (build)
F5 (run)

Ergebnis: wird ohne Fehler compiliert und gelinkt, Ausführung fehlerfrei. :prima:

Tipp:
wie die meisten C/C++ Programmierer sicher wissen, kann man (eigene) .c, .cpp, .h, .hpp etc. files in den Raspi-Ordner
/usr/local/include/
kopieren, dadurch werden sie anschließend von gcc automatisch gefunden, wenn man sie mit #include einbindet.
Im Falle von BrickPi3 betrifft das ausschließlich 2 Files, nämlich
BrickPi3.cpp
und
BrickPi.h

Sie müssen dann danach also nicht mehr immer zusätzlich im aktuellen Arbeits-Directory vorhanden sein.

update:
matt hat geschrieben:As of BrickPi3 PR #67 BrickPi3.h and BrickPi3.cpp are now installed to /usr/local/include.

Benutzeravatar
HaWe
Administrator
Administrator
Beiträge: 5399
Registriert: 11. Jan 2006 21:01
Wohnort: ein kleiner Planet in der Nähe von Beteigeuze

Re: BrickPi3: Quick Guide (mit C/C++ & "stackable" Shields)

Beitragvon HaWe » 28. Apr 2017 10:42

Motoren und Sensoren anschließen:

Anm.:
Nicht unbedingt für Sensoren, aber auf jeden Fall für Motoren wird eine externe Zusatz-Spannungsquelle benötigt (ca. 8-12V).
Zusätzlich den Spannungsschalter einschalten.
Jetzt wird auch der Raspi über die Zusatzspannungsquelle und den 5V GPIO-Header Pin versorgt.
Die gelbe Blink-LED auf dem BrickPi3 gibt Aufschluss über den Batteriestatus:
schnelles Blinken (4x/s.): zu schwach, 2x/s.: gerade halbwegs ausreichend, 1x/s.: sehr gut.
Zusätzlich gibt die rote Status-LED auf dem Raspi Aufschluss darüber, ob 5V anliegen (rot an: OK, rot aus: low voltage!)


Bild
Die Buchsen halte ich für etwas sehr seltsam angeordnet und ausgerichtet, abe das ist sicher auch teilw. Geschmackssache.


Definition der Sensor- und Motor-Ports:

Code: Alles auswählen

// Sensor ports
#define PORT_1 0x01
#define PORT_2 0x02
#define PORT_3 0x04
#define PORT_4 0x08

// Motor ports
#define PORT_A 0x01
#define PORT_B 0x02
#define PORT_C 0x04
#define PORT_D 0x08



BrickPi class (public):

Code: Alles auswählen

class BrickPi3{
  public:
    // Default to address 1, but the BrickPi3 address could have been changed.
    BrickPi3(uint8_t addr = 1);
   
    // Confirm that the BrickPi3 is connected and up-to-date
    int     detect(bool critical = true);
   
    // Get the manufacturer (should be "Dexter Industries")
    int     get_manufacturer(char *str);
    // Get the board name (should be "BrickPi3")
    int     get_board(char *str);
    // Get the hardware version number
    int     get_version_hardware(char *str);
    // Get the firmware version number
    int     get_version_firmware(char *str);
    // Get the serial number ID that is unique to each BrickPi3
    int     get_id(char *str);
   
    // Control the LED
    int     set_led(uint8_t value);
   
    // Get the voltages of the four power rails
    int     get_voltage_3v3    (float &voltage);
    float   get_voltage_3v3    ();
    int     get_voltage_5v     (float &voltage);
    float   get_voltage_5v     ();
    int     get_voltage_9v     (float &voltage);
    float   get_voltage_9v     ();
    int     get_voltage_battery(float &voltage);
    float   get_voltage_battery();
   
    // Configure a sensor
    int     set_sensor_type(uint8_t port, uint8_t type, uint16_t flags = 0, i2c_struct_t *i2c_struct = NULL);
    // Configure and trigger an I2C transaction
    int     transact_i2c(uint8_t port, i2c_struct_t *i2c_struct);
    // Get sensor value(s)
    int     get_sensor(uint8_t port, void *value);
   
    // Set the motor PWM power
    int     set_motor_power(uint8_t port, int8_t power);
    // Set the motor target position to run to
    int     set_motor_position(uint8_t port, int32_t position);
    // Set the motor speed in degrees per second. As of FW version 1.4.0, the algorithm regulates the speed, but it is not accurate.
    int     set_motor_dps(uint8_t port, int16_t dps);
    // Set the motor limits. Only the power limit is implemented. Use the power limit to limit the motor speed/torque.
    int     set_motor_limits(uint8_t port, uint8_t power, uint16_t dps);
    // Get the motor status. State, PWM power, encoder position, and speed (in degrees per second)
    int     get_motor_status(uint8_t port, uint8_t &state, int8_t &power, int32_t &position, int16_t &dps);
    // Offset the encoder position. By setting the offset to the current position, it effectively resets the encoder value.
    int     offset_motor_encoder(uint8_t port, int32_t position);
    // Get the encoder position
    int     get_motor_encoder(uint8_t port, int32_t &value);
    int32_t get_motor_encoder(uint8_t port);
   
    // Reset the sensors (unconfigure), motors (float with no limits), and LED (return control to the firmware).
    int     reset_all();
   
};

Benutzeravatar
HaWe
Administrator
Administrator
Beiträge: 5399
Registriert: 11. Jan 2006 21:01
Wohnort: ein kleiner Planet in der Nähe von Beteigeuze

Re: BrickPi3: Quick Guide (mit C/C++ & "stackable" Shields)

Beitragvon HaWe » 28. Apr 2017 12:31

Example: NXT Sensor Test Programm sensors_nxt.c


Anm.:
Analoge Sensorwerte sind 12-bit ADC, also 0-4095 (statt 10-bit ADC von 0-1023 wie bei Lego üblich).
Wenn man will, kann man sie durch 4 dividieren (oder >>2), dann hat man wieder den Genauigkeits-Bereich von Lego-Analog-Sensoren.


Code: Alles auswählen

/*
 *  https://www.dexterindustries.com/BrickPi/
 *  https://github.com/DexterInd/BrickPi3
 *
 *  Copyright (c) 2017 Dexter Industries
 *  Released under the MIT license (http://choosealicense.com/licenses/mit/).
 *  For more information, see https://github.com/DexterInd/BrickPi3/blob/master/LICENSE.md
 *
 *  This code is an example for reading the encoders of motors connected to the BrickPi3.
 *
 *  Hardware: Connect NXT sensors to the sensor ports. Color sensor to PORT_1. Ultrasonic sensor to PORT_2. Light sensor to PORT_3. Touch sensor to PORT_4 (EV3 or NXT touch sensor).
 *
 *  Results:  When you run this program, you should see the values for each sensor.
 *
 *  Example compile command:
 *    g++ -o program "sensors_nxt.c"
 *  Example run command:
 *    sudo ./program
 *
 */

#include "BrickPi3.cpp" // for BrickPi3
#include <stdio.h>      // for printf
#include <unistd.h>     // for usleep
#include <signal.h>     // for catching exit signals

BrickPi3 BP;

void exit_signal_handler(int signo);

int main(){
  signal(SIGINT, exit_signal_handler); // register the exit function for Ctrl+C
 
  BP.detect(); // Make sure that the BrickPi3 is communicating and that the firmware is compatible with the drivers.
 
  int error;
 
  BP.set_sensor_type(PORT_1, SENSOR_TYPE_NXT_COLOR_FULL);
  BP.set_sensor_type(PORT_2, SENSOR_TYPE_NXT_ULTRASONIC);
  BP.set_sensor_type(PORT_3, SENSOR_TYPE_NXT_LIGHT_ON);
  BP.set_sensor_type(PORT_4, SENSOR_TYPE_TOUCH);
 
  sensor_color_t      Color1;
  sensor_ultrasonic_t Ultrasonic2;
  sensor_light_t      Light3;
  sensor_touch_t      Touch4;
 
  while(true){
    error = 0;
   
    if(BP.get_sensor(PORT_1, &Color1)){
      error++;
    }else{
      printf("Color sensor (S1): detected %d red %4d green %4d blue %4d ambient %4d   ", Color1.color, Color1.reflected_red, Color1.reflected_green, Color1.reflected_blue, Color1.ambient);
    }
   
    if(BP.get_sensor(PORT_2, &Ultrasonic2)){
      error++;
    }else{
      printf("Ultrasonic sensor (S2): CM %5.1f Inches %5.1f   ", Ultrasonic2.cm, Ultrasonic2.inch);
    }
   
    if(BP.get_sensor(PORT_3, &Light3)){
      error++;
    }else{
      printf("Light sensor (S3): reflected %4d   ", Light3.reflected);
    }
   
    if(BP.get_sensor(PORT_4, &Touch4)){
      error++;
    }else{
      printf("Touch sensor (S4): pressed %d   ", Touch4.pressed);
    }
   
    if(error == 4){
      printf("Waiting for sensors to be configured");
    }
   
    printf("\n");
   
    usleep(20000);
  }
}

// Signal handler that will be called when Ctrl+C is pressed to stop the program
void exit_signal_handler(int signo){
  if(signo == SIGINT){
    BP.reset_all();    // Reset everything so there are no run-away motors
    exit(-2);
  }
}
Gruß,
HaWe
±·≠≈²³αβγδε∂ζλμνπξφωΔΦ≡ΠΣΨΩ∫√∀∃∈∉∧∨¬⊂⊄∩∪∅∞®
NXT NXC SCHACHROBOTER: https://www.youtube.com/watch?v=Cv-yzuebC7E

Benutzeravatar
HaWe
Administrator
Administrator
Beiträge: 5399
Registriert: 11. Jan 2006 21:01
Wohnort: ein kleiner Planet in der Nähe von Beteigeuze

Re: BrickPi3: Quick Guide (mit C/C++ & "stackable" Shields)

Beitragvon HaWe » 28. Apr 2017 14:47

Example: Motor Test Programm motors.c:


Achtung:
Man muss darauf achten, dass die Zusatz-Batterien für die Motor-Treiber genügend Spannung liefern, sonst schaltet sie der BrickPi3 automatisch ab, mit SPI Fehler - und dann hilft nur ein Reboot mit frischen Batterien!


Code: Alles auswählen

/*
 *  https://www.dexterindustries.com/BrickPi/
 *  https://github.com/DexterInd/BrickPi3
 *
 *  Copyright (c) 2017 Dexter Industries
 *  Released under the MIT license (http://choosealicense.com/licenses/mit/).
 *  For more information, see https://github.com/DexterInd/BrickPi3/blob/master/LICENSE.md
 *
 *  This code is an example for reading the encoders of motors connected to the BrickPi3.
 *
 *  Hardware: Connect EV3 or NXT motor(s) to any of the BrickPi3 motor ports.
 *
 *  Results:  When you run this program, you should see the encoder value for each motor. By manually rotating motor A, the other motor(s) will be controlled. Motor B power will be controlled, Motor C speed will be controlled, and motor D position will be controlled.
 *
 *  Example compile command:
 *    g++ -o program "motors.c"
 *  Example run command:
 *    sudo ./program
 *
 */

#include "BrickPi3.cpp" // for BrickPi3
#include <stdio.h>      // for printf
#include <unistd.h>     // for usleep
#include <signal.h>     // for catching exit signals

BrickPi3 BP;

void exit_signal_handler(int signo);

int main(){
  signal(SIGINT, exit_signal_handler); // register the exit function for Ctrl+C
 
  BP.detect(); // Make sure that the BrickPi3 is communicating and that the firmware is compatible with the drivers.
 
  // Reset the encoders
  BP.offset_motor_encoder(PORT_A, BP.get_motor_encoder(PORT_A));
  BP.offset_motor_encoder(PORT_B, BP.get_motor_encoder(PORT_B));
  BP.offset_motor_encoder(PORT_C, BP.get_motor_encoder(PORT_C));
  BP.offset_motor_encoder(PORT_D, BP.get_motor_encoder(PORT_D));
 
  while(true){
    // Read the encoders
    int32_t EncoderA = BP.get_motor_encoder(PORT_A);
    int32_t EncoderB = BP.get_motor_encoder(PORT_B);
    int32_t EncoderC = BP.get_motor_encoder(PORT_C);
    int32_t EncoderD = BP.get_motor_encoder(PORT_D);
   
    // Use the encoder value from motor A to control motors B, C, and D
    BP.set_motor_power(PORT_B, EncoderA < 100 ? EncoderA > -100 ? EncoderA : -100 : 100);
    BP.set_motor_dps(PORT_C, EncoderA);
    BP.set_motor_position(PORT_D, EncoderA);
   
    // Display the encoder values
    printf("Encoder A: %6d  B: %6d  C: %6d  D: %6d\n", EncoderA, EncoderB, EncoderC, EncoderD);
   
    // Delay for 20ms
    usleep(20000);
  }
}

// Signal handler that will be called when Ctrl+C is pressed to stop the program
void exit_signal_handler(int signo){
  if(signo == SIGINT){
    BP.reset_all();    // Reset everything so there are no run-away motors
    exit(-2);
  }
}
Gruß,
HaWe
±·≠≈²³αβγδε∂ζλμνπξφωΔΦ≡ΠΣΨΩ∫√∀∃∈∉∧∨¬⊂⊄∩∪∅∞®
NXT NXC SCHACHROBOTER: https://www.youtube.com/watch?v=Cv-yzuebC7E

Benutzeravatar
HaWe
Administrator
Administrator
Beiträge: 5399
Registriert: 11. Jan 2006 21:01
Wohnort: ein kleiner Planet in der Nähe von Beteigeuze

Re: BrickPi3: Quick Guide (mit C/C++ & "stackable" Shields)

Beitragvon HaWe » 29. Apr 2017 22:19

Vorschlag:
Muster für eine BrickPi3 Multithreading-Architektur


compile/build flags:
-pthread -lwiringPi

wiringPi Installation:
siehe viewtopic.php?f=78&t=8689&start=15#p67924


Code: Alles auswählen


#include <stdbool.h>    // boolean types and values
#include <stdio.h>      // files, keyboard IO (getchar())
#include <termio.h>     // low level XBD (termios, ioctl)
#include <unistd.h>     // POSIX/LINUX symbolic constants and types
#include <string.h>     // strings+arrays (memcpy())
#include <pthread.h>    // multithreading
#include <wiringPi>     // GPIOs, delay, millis

#include "BrickPi3.cpp" // for BrickPi3
#include <signal.h>     // for catching exit signals



//===============================================
// create BrickPi instance
//===============================================

BrickPi3 BP;


//===============================================
// Signal handler to be called when Ctrl+C is pressed
//===============================================

void exit_signal_handler(int signo){
  if(signo == SIGINT){
     MT_active = 0;     // signalize threads to terminate by themselves 
     fprintf( stdout, "\naborted by [CTRL+C]\n" );      // optional
  }
}




//===============================================
// mimics conio.h kbhit()
//===============================================

bool kbhit(void)
{
    struct termios original;
    tcgetattr(STDIN_FILENO, &original);
    struct termios term;
    memcpy(&term, &original, sizeof(term));
    term.c_lflag &= ~ICANON;
    tcsetattr(STDIN_FILENO, TCSANOW, &term);
    int characters_buffered = 0;
    ioctl(STDIN_FILENO, FIONREAD, &characters_buffered);
    tcsetattr(STDIN_FILENO, TCSANOW, &original);
    bool pressed = (characters_buffered != 0);

    return pressed;
}

//===============================================
//  single threads & MT thread control
//===============================================

pthread_mutex_t  mutexBP;

volatile int    MT_active=1, Ts1=0, Ts2=0, Ts3=0;  // semaphores to control and monitor MT


void* thread1Name(void *) {
  Ts1=1;     // indicate thread 1 was started

  while(MT_active) {
    ///... (code/loop)
    delay(1);    // optional, arbitrarily
  }
  Ts1=0;     // indicate thread 1 was stopped
  fprintf( stdout, "\nthread 1 exit message\n" );      // optional
  return NULL;
}


void* thread2Name(void *) {
  Ts2=1;     // indicate thread 2 was started

  while(MT_active) {
    ///... (code/loop)   
    delay(10);    // optional, arbitrarily
  }
  Ts2=0;     // indicate thread 2 was stopped
  fprintf( stdout, "\nthread 2 exit message\n" );      // optional
  return NULL;
}


void* thread3Name(void *) {
  Ts3=1;     // indicate thread 3 was started

  while(MT_active) {
    ///... (code/loop)
    delay(100);    // optional, arbitrarily
  }
  Ts3=0;     // indicate thread 3 was stopped
  fprintf( stdout, "\nthread 3 exit message\n" );      // optional
  return NULL;
}

//===============================================
// main()
//===============================================

int main() {

    signal(SIGINT, exit_signal_handler);   // register the exit function for Ctrl+C
    pthread_mutex_init (&mutexBP, NULL);   // init a mutex for Brickpi access
   
    //----------------------------------------
    // mutex handling: lock and unlock
    //----------------------------------------
    pthread_mutex_lock (&mutexBP);        // lock the following variable operations by the BrickPi mutex
   
       // Make sure that the BrickPi3 is communicating and that the firmware is compatible with the drivers:
       BP.detect();
       // Reset the encoders:
       BP.offset_motor_encoder(PORT_A, BP.get_motor_encoder(PORT_A));
       BP.offset_motor_encoder(PORT_B, BP.get_motor_encoder(PORT_B));
       BP.offset_motor_encoder(PORT_C, BP.get_motor_encoder(PORT_C));
       BP.offset_motor_encoder(PORT_D, BP.get_motor_encoder(PORT_D));
   
    pthread_mutex_unlock (&mutexBP);     // release the mutex to write/read by different threads

     
    //----------------------------------------
    //create and start the pthread threads
    //----------------------------------------
    pthread_t   tid1, tid2, tid3;   // thread IDs
   
    pthread_create(&tid1, NULL, thread1Name, NULL);   
    pthread_create(&tid2, NULL, thread2Name, NULL);   
    pthread_create(&tid3, NULL, thread3Name, NULL);

    delay(1);  // give the threads a chance to start
   
    //----------------------------------------
    // keyboard handler: terminate by ESC key
    //----------------------------------------
    while(MT_active) {
      if ( kbhit() ) {
        int key = getchar();
        if (key==27) {    // ESC == ASCII 27
           MT_active = 0;
           fprintf( stdout, "\naborted by [ESC]\n" );      // optional
           break();
        }
      }   
      // optional: rest of a perpetual main() code
      // instead, put BP code into a proprietary thread
      delay(100);  // optional
    }


    //----------------------------------------
    // wait for threads to join before exiting
    //----------------------------------------
    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);
    pthread_join(tid3, NULL);

    //----------------------------------------
    // reset and then terminate
    //----------------------------------------
   
    pthread_mutex_lock (&mutexBP);  // not compellingly required here, just to demonstrate mutexes
       BP.reset_all();    // Reset everything so there are no run-away motors
    pthread_mutex_unlock (&mutexBP); 
   
    return 0;
}
Gruß,
HaWe
±·≠≈²³αβγδε∂ζλμνπξφωΔΦ≡ΠΣΨΩ∫√∀∃∈∉∧∨¬⊂⊄∩∪∅∞®
NXT NXC SCHACHROBOTER: https://www.youtube.com/watch?v=Cv-yzuebC7E

Benutzeravatar
HaWe
Administrator
Administrator
Beiträge: 5399
Registriert: 11. Jan 2006 21:01
Wohnort: ein kleiner Planet in der Nähe von Beteigeuze

Re: BrickPi3: Quick Guide (mit C/C++ & "stackable" Shields)

Beitragvon HaWe » 3. Mai 2017 19:20

Motor API:
neue Funktionen für
reset Motor-Encoder
und
rotate relative Degrees
(s. github Repository, Link s. oben)


Update, was die Unterstützung für IO-Hardware am BrickPi angeht:

Dexter bietet ausschließlich Support für Original Lego Sensoren, Treiber-Anfragen zu 3rd Party Sensoren etc. werden kategorisch abgelehnt.
Gruß,
HaWe
±·≠≈²³αβγδε∂ζλμνπξφωΔΦ≡ΠΣΨΩ∫√∀∃∈∉∧∨¬⊂⊄∩∪∅∞®
NXT NXC SCHACHROBOTER: https://www.youtube.com/watch?v=Cv-yzuebC7E


Zurück zu „allgemeine / Nicht-Lego-Robotik und Elektronik“

Wer ist online?

Mitglieder in diesem Forum: Google Adsense [Bot] und 9 Gäste

Lego Mindstorms EV3, NXT und RCX Forum : Haftungsauschluss