PORTs (Ausgänge) prüfen

Guten Abend allerseits,

mal wieder die Situation gehabt, in der man nicht sicher sagen konnte, ob der Arduino Pin
stabil durchgeschalten hat oder die Verdrahtung / das Bauteil fehlerhaft ist.
Meine Überlegung war es einen kleinen Sketch zu schreiben, welcher möglichst alle verfügbaren Pins in einem vorgegebenen Takt ein und aus schaltet. Die damit geschalteten Pins kann man dann Hardware seitig mit einer Last ~15mA testen.

enum {UNO, MEGA2560}; //Modelle
enum {PB, PC, PD};    //PORTs
#define Arduino UNO   //UNO, MEGA2560
const uint32_t output_takt = 1000;
const byte output_mask[2][3][2] =
{ {//UNO
    {0B0, 0B00111111}, //PB
    {0B0, 0B00111111}, //PC
    {0B0, 0B11111110}  //PD
  },
  {//MEGA2560...
    {0B0, 0B0}, //PB
    {0B0, 0B0}, //PC
    {0B0, 0B0}  //PD
  } };

void setup()
{
  Serial.end();
#if Arduino == UNO
  DDRB = output_mask[UNO][PB][1]; //PORT B0-5 als OUTPUT
  DDRC = output_mask[UNO][PC][1]; //PORT C0-5 als OUTPUT
  DDRD = output_mask[UNO][PD][1]; //PORT D1-7 als OUTPUT
#elif Arduino == MEGA2560
  Serial1.end(); Serial2.end(); Serial3.end();
  //...
#endif
}

void loop()
{
  static uint8_t mode;
  static uint32_t vor_ms;
  uint32_t akt_ms = millis();

  if (akt_ms - vor_ms >= output_takt)
  {
    vor_ms = akt_ms;
    if (mode == 0) mode = 1;
    else mode = 0;
#if Arduino == UNO
    PORTB = output_mask[UNO][PB][mode];
    PORTC = output_mask[UNO][PC][mode];
    PORTD = output_mask[UNO][PD][mode];
#elif Arduino == MEGA2560
    //...
#endif
  }
}

Bitte bei Fehleren oder Anmerkungen melden.
Ich danke Euch
grillgemuese :slight_smile:

for(int i = 0  i < NUM_DIGITAL_PINS; i++)
{
   // zappel eine Weile mit dem Pin i
}

Bei Arduinos mit UART-USB Wandler, sollte man den RxD Pin nicht zappeln lassen. Denn nicht alle haben da Angstwiderstände.

Ich weiß nicht wieso Du hier die Ports bemühen möchtest. Wenn Du LEDs mit Vorwiderstand als Last nehmen möchtest dann ist ein digitalWrite() längst viel zu schnell.

Außerdem sollte man den Ausgang jeweils als Quelle und Senke kontrollieren.

Wieso brauchst Du das Serial.end() ?

Grüße Uwe

uwefed:
...ist ein digitalWrite() längst viel zu schnell.

Außerdem sollte man den Ausgang jeweils als Quelle und Senke kontrollieren.

Wieso brauchst Du das Serial.end() ?

Wieder neue Begriffe kennengelernt. :slight_smile:
Quelle_und_Senke

Auf digitalWrite habe ich verzichtet, da ich mal etwas mit der Portmanipulation spielen wollte.
Als Last hatte ich einen Widerstand von 330 Ohm präferiert, welcher an GND liegt.
Mit meinem Pocket Oszi kann man die HIGH Pegel "überprüfen".
Ein guter Punkt ist die Potential Festellung bei dem Pegel LOW, welche ich mit dem Widerstand zu GND nicht sicher prüfen konnte.

Serial.end() hatte ich anfangs verwendet um die serielle Schnittstelle zu deaktivieren, scheint sich aber bereits durch PORTD 0 & 1 erledigt zu haben.

Danke Dir
grillgemuese :slight_smile:

Mit einem Widerstand gegen Masse kontrollierst Du nur ob der Ausgangstransistor 5V an den Ausgang schalten kann (= Stromquelle; Strom fließt heraus) . Jeder Ausgang hat aber auch einen Transistor der den Ausgang gegen Masse schaltet ( = Stromsenke; Strom fließt von der Versorgungsspannung über die Last in das Pin/Ausgang hinein). Am einfachsten ist Du schaltest alle Widerstände zusammen und schaltest sie mit einem Schalter oder einer Brücke mal gegen Masse und mal gegen +5V.

Laut Datenblatt muß ein Ausgang bei 20mA Ausgangsstrom, 5V Versorgungsspannung und Umgebungstemperatur 85°C
bei HIGH mehr als 4,2V "liefern"
bei LOW weniger als 0,9V

Meines Wissens wird die serielle Schnittstelle nur durch Serial.begin initialisiert. Ansonsten sind die Pins normale pins an denen aber der USB-Adapter hängt. Je nach Modell des Arduinos/Nachbaus sind widerstände zwischen den beiden Controllern/ICs eingebaut.

Grüße Uwe