[gelöst] Hilfe zu Motorcontroller MC33926

Hallo allerseits,
da ich Probleme mit dem Relais-Board hatte, bin ich nun auf den Motorcontroller MC33926 umgestiegen.
Nun stellt sich mir die Frage, kann ich meinen Sketch 1 zu 1 über nehmen oder wasmuss ich verändern ?
Vielen Dank für Eure Hilfe.

Edit: Sketch vergessen...

Hier nun der Sketch

/*######################################################
#                                                      #
#  SolarTracker mit S0 Zähler                          #
#  Version 0.8                                         #
#                                                      #
#  Sonnenfolger, der mittels LDR immer                 #
#  den hellsten Punkt am Himmel sucht                  #
#                                                      #
#  written from Stefan Blinkmann                       #
#  01.04.2014 - 20:53                                  #
#                                                      #
########################################################*/
//#include <SPI.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2);
byte bell[8]   = { B00100, B01110, B01110, B01110, B11111, B00000, B00100, B00000 };
byte sun[8]    = { B00100, B10101, B01110, B11111, B01110, B10101, B00100, B00000 };
byte smili[8]  = { B00000, B01010, B01010, B00000, B00100, B10001, B01110, B00000 };
byte left[8]   = { B00010, B00110, B01110, B11110, B01110, B00110, B00010, B00000 };
byte right[8]  = { B01000, B01100, B01110, B01111, B01110, B01100, B01000, B00000 };
byte ae[8]     = { B01010, B00000, B01110, B00001, B01111, B10001, B01111, B00000 };

volatile int impState = 0;
volatile int lastimpState = 0;
int bounceTime  = 100;
unsigned long act_imp;
unsigned long last_imp;
double impCounter = 0;
unsigned long millisBetween;
unsigned long lastMillis;
unsigned long watt;

double kwh = 0.000;                                   // Kilowattstunden
double Preis =  0.2622;                               // Preis einer Kilowattstunde in Euro
double euro;
char tmp1[16];
char tmp2[16];

/*--- Solar Tracker ---*/
int moveleft = 4;                                     // Motor pin left
int moveright = 5;                                    // Motor pin right
int ldrleft = 1;                                      // Name und Pin-Nr (LDR links)
int ldrcenter = 2;                                    // Name und Pin-Nr (LDR mitte)
int ldrright = 3;                                     // Name und Pin-Nr (LDR rechts)
int LDR_hell = 0;                                     // Wert von LDR_hell
unsigned long Zeit_dtime;                             // Zeit-Variable für dtime
unsigned long pauseMillis;                            // Zeit-Variable für pause
/*--- Solar Tracker ---*/

void setup () 
{
  Serial.begin(9600);
  pinMode(2, INPUT);
  digitalWrite(2, HIGH);
  pinMode(7, OUTPUT);                                 // LCD Hintergrundbeleuchtung
  pinMode(moveleft, OUTPUT);                          // Motor left als Ausgang deklarieren
  pinMode(moveright, OUTPUT);                         // Motor right als Ausgang deklarieren
  digitalWrite(moveleft, HIGH);
  digitalWrite(moveright,HIGH);
  lcd.init();
  lcd.backlight();
  lcd.createChar(0, bell);                            // Sonderzeichen Glocke
  lcd.createChar(1, sun);                             // Sonderzeichen Sonne
  lcd.createChar(2, smili);                           // Sonderzeichen Smiley
  lcd.createChar(3, left);                            // Sonderzeichen left arrow
  lcd.createChar(4, right);                           // Sonderzeichen right arrow
  lcd.createChar(5, ae);                              // Sonderzeichen right arrow
  digitalWrite(7, HIGH);                              // LCD Hintergrundbeleuchtung AN
  lcd.setCursor(0,0);
  lcd.write(1);                                       // Sonne links
  lcd.setCursor(2,0);
  lcd.print(F("Starte Solar"));
  lcd.setCursor(15,0);
  lcd.write(1);                                       // Sonne rechts
  lcd.setCursor(3,1);
  lcd.print(F("Z"));
  lcd.write(5);
  lcd.print(F("hler ..."));
  delay(5000);
  lcd.clear();
  millisBetween = 0;
  lastMillis = 0;
  lastimpState = 0;
  watt = 0;
  Zeit_dtime = 0;
  pauseMillis = 0;
}


void loop () 
{
  impState = digitalRead(2);
  act_imp = millis();
  unsigned long time = millis();
  
  if(act_imp - last_imp > bounceTime)
  {

  if (impState != lastimpState) {
    if (impState == LOW) {
      last_imp = act_imp;
      impCounter++;
      
      millisBetween = time-lastMillis;
      lastMillis = time;
    }
  }
  lastimpState = impState;
  }
  
  /*--- Solar Tracker ---*/
  int left = analogRead(ldrleft);                     // LDR links einlesen
  int right = analogRead(ldrright);                   // LDR rechts einlesen
  int center = analogRead(ldrcenter);                 // LDR mitte einlesen
  int rightN = right +20;                             // (-12 )LDR rechts an den linken angleichen, bei +47 sind L u. R vom Wert her gleich
  int dtime = 1000;                                   // Such/Beweg geschwindigkeit
  int tol = 2;                                        // (28) tolleranz zwischen LDR-links und LDR-rechts
  unsigned long pause = 120000;                       // 2 min Pause in milliSek , wenn Links und Rechts gleich sind
  int alr = (left + rightN) / 2;                      // durchschnitt LDR-links u. LDR-rechts
  int LDR_hell = center;                              // LDR-mitte auch als LDR_hell deklarieren, für Nacht/Tag modus
  int dhoriz = alr - center;                          // check the diffirence of left/rigt and center
  int LR = left - rightN;
  
  
       display_Counter();
       digitalWrite(7, HIGH);                         // LCD Hintergrundbeleuchtung AN
       
  if((millis() - pauseMillis) > pause){               // Pause wenn L&R gleich sind
    
   if((millis() - Zeit_dtime) > dtime){               // Such/Beweg geschwindigkeit
    Zeit_dtime = millis();
    
  Serial.print(F("L:"));
  Serial.println(left);
  Serial.print(F("C:"));
  Serial.println(center);
  Serial.print(F("R:"));
  Serial.println(rightN);
    
  if (-1*tol > dhoriz || dhoriz > tol)                // check if the diffirence is in the tolerance else change horizontal angle
  {
    
    if (left < rightN)                                // ist links kleiner als rechts, fahre nach links
    {
      //Serial.println(F("Move -->"));
      digitalWrite(moveright, HIGH);                  // einzelne schritte -
      digitalWrite(moveleft, LOW); 
      lcd.setCursor(14,1);
      lcd.write(4);
    }
    else if (left > rightN)                           // ist links größer als rechts, fahre nach rechts
    {
      //Serial.println(F("<-- Move"));      
      digitalWrite(moveleft, HIGH);                   // einzelne schritte +
      digitalWrite(moveright, LOW);
      lcd.setCursor(14,1);
      lcd.write(3);
    }
    else if (left == rightN)                          // sind links u. rechts gleich, in dieser stellung für 30 sek. bleiben
    {
      pauseMillis = millis();
      //Serial.println(F("Horizontal Optimal !"));
      digitalWrite(moveleft, HIGH);
      digitalWrite(moveright, HIGH);
      lcd.setCursor(14,1);
      lcd.write(2);
      }
     
    }

    if (left != rightN)  { /* nix */ }                 // sind links und rechts ungleich, weiter suchen...

   } /* Such/Beweg geschwindigkeit ende */ 
  }    /* Pause wenn L&R gleich sind ende */
  
 }/*--- Loop Ende ---*/
 
 void display_Counter(){
   kwh = impCounter / 1000;
    dtostrf(kwh, 1, 3, tmp1);
    lcd.setCursor(0,0);
    lcd.print(tmp1);
    lcd.print(F(" KWh"));
    
    euro = kwh * Preis;
    dtostrf(euro, 1, 3, tmp2);
    lcd.setCursor(0, 1);
    lcd.print(tmp2);
    lcd.print(" EUR");
    
    watt = 3600000 / millisBetween;
    
    if (int(watt) > 500) { watt = 500; }                  // ist Watt grösser als 500 , zeige nur 500 an

    lcd.setCursor(11,0);
    if (int(watt) <= -1){ lcd.print("  "); watt = 0;}     // ist Watt kleiner oder gleich -1, setze watt auf 0
    else if (int(watt) < 100 ) { lcd.print(' '); }        //stellt ein leeres Feld voran, wenn Watt kleiner als 100
    else if(int(watt) < 10 ) { lcd.print('  '); }         //stellt zwei leere Felder voran, wenn Watt kleiner als 10
    lcd.print(int(watt));
    lcd.setCursor(15, 0);
    lcd.print("W");
 }

Ein Verdrahtungsdiagramm würde auch helfen.

In den Kommentaren steht etwas von Schritten. Hattest bzw. hast Du Schrittmotoren im Einsatz?

Hallo Pylon,

pylon:
Ein Verdrahtungsdiagramm würde auch helfen.

In den Kommentaren steht etwas von Schritten. Hattest bzw. hast Du Schrittmotoren im Einsatz?

Keinen Schrittmotor, einen Linearmotor, der einfach über PIN 4 und 5 mittels eines Relais,hin und her geschaltet wird.
Und das Relais soll duch den MC33926 ersetzt werden.

Leider findet man nur Anleitungen usw für den Dual MC33926.
Ich habe abr nur den einfachen, weil ja nur ein Motor.

Und der MC33926 hat ja ne Menge Anschlussmöglichkeiten und ich weiß ehrlich gesagt nicht wie man den Anschließt. Ich möchte erstmal kein PWM benutzen.
Das kommt vieleicht später...

An VIn musst du den Plusspol der Spannungsquelle für deinen Motor anschließen.
Die Spule deines Motors musst du an Out1 und Out2 anschließen (eventuell über Freilaufdioden).
Die Outputs werden über die beiden Pins In1 und In2 gesteuert (und damit auch die Drehrichtung des Motors), die kommen an den Arduino.
Den En pin musst du an 5V vom Arduino legen, da sonst der Chip im Sleepmodus ist.
VDD an die 5V vom Arduino.
GND an GND

Masse (GND) vom Arduino und der Spannungquelle für den Motor musst du zusammen legen.

Die beiden PWM Kanäle schließt du an GND oder 5V musst du mal probieren.
SLEW an GND.
INV an GND (an 5V hat zur Folge, dass das Signal an den In-Pins invertiert wird).
FB an LOW.

Über den Pin SF kannst du feststellen, ob es irgendein Problem mit dem Board gibt, oder ob einer der PWM-Kanäle gerade einen der Outputs ausschaltet. Dazu musst du einfach nur über einen der Digitalpins überprüfen, ob er auf LOW ist.

:wink:

Hallo Addi2438,
Vielen Dank für deine Hilfe.
Zwei Fragen habe ich noch, wie Dimensioniert muss denn die Freilaufdiode sein ?
Und wo bringe ich die ein ?
Ich habe ja eine fertige Relais-Platine:

Cetax:
Hallo Addi2438,
Vielen Dank für deine Hilfe.
Zwei Fragen habe ich noch, wie Dimensioniert muss denn die Freilaufdiode sein ?
Und wo bringe ich die ein ?
Ich habe ja eine fertige Relais-Platine:

Jetzt verstehe ich nicht ganz Deine Frage.
Der MC33926 hat die Freilufdioden bereits integriert. siehe http://www.pololu.com/file/0J233/MC33926.pdf
Beim Relais bzw grundsätzlich bei induktiven Lasten wird die Diode antiparalell zur Spule bzw induktiven Last geschaltet. Auf der Platine sind das die kleinen Rot-schwarzen Bauteile links von den Relais. Normalerweis reichen kleine 1N4148 Dioden. Bei Motoren sind stärkere Dioden notwendig. Sie sind im Datenblatt der H-Brücke angegeben.
Grüße Uwe

Hallo Uwe,

uwefed:

Cetax:
Hallo Addi2438,
Vielen Dank für deine Hilfe.
Zwei Fragen habe ich noch, wie Dimensioniert muss denn die Freilaufdiode sein ?
Und wo bringe ich die ein ?
Ich habe ja eine fertige Relais-Platine:

Jetzt verstehe ich nicht ganz Deine Frage.

ICH AUCH NICHT ! :blush:
Sorry, irgendwie hatte ich die letzten Tage zu wenig schlaf...

uwefed:
Der MC33926 hat die Freilufdioden bereits integriert. siehe http://www.pololu.com/file/0J233/MC33926.pdf
Beim Relais bzw grundsätzlich bei induktiven Lasten wird die Diode antiparalell zur Spule bzw induktiven Last geschaltet. Auf der Platine sind das die kleinen Rot-schwarzen Bauteile links von den Relais. Normalerweis reichen kleine 1N4148 Dioden. Bei Motoren sind stärkere Dioden notwendig. Sie sind im Datenblatt der H-Brücke angegeben.
Grüße Uwe

Ich werde es erstmal ohne Freilaufdioden probieren. Und natürlich ohne Ralais, sondern wie im Titel mit dem MC33926 :blush:
Keine Ahnung warum ich das Bild mit der Relais-Platine gepostet habe... :roll_eyes:

Hallo addi2438,
Leider sagt der kontroller garnichts...
Habe alles so angeschlossen wie du geschrieben hast.
Aber da rührt sich nix...

Addi2438:
An VIn musst du den Plusspol der Spannungsquelle für deinen Motor anschließen.
Die Spule deines Motors musst du an Out1 und Out2 anschließen (eventuell über Freilaufdioden).
Die Outputs werden über die beiden Pins In1 und In2 gesteuert (und damit auch die Drehrichtung des Motors), die kommen an den Arduino.
Den En pin musst du an 5V vom Arduino legen, da sonst der Chip im Sleepmodus ist.
VDD an die 5V vom Arduino.
GND an GND

Masse (GND) vom Arduino und der Spannungquelle für den Motor musst du zusammen legen.

Die beiden PWM Kanäle schließt du an GND oder 5V musst du mal probieren.
SLEW an GND.
INV an GND (an 5V hat zur Folge, dass das Signal an den In-Pins invertiert wird).
FB an LOW.

Über den Pin SF kannst du feststellen, ob es irgendein Problem mit dem Board gibt, oder ob einer der PWM-Kanäle gerade einen der Outputs ausschaltet. Dazu musst du einfach nur über einen der Digitalpins überprüfen, ob er auf LOW ist.

:wink:

Hast du oder jemand anderes noch eine Idee ?

Wie steuerst du das Shield dem im Sketch an?
Hast du die beiden PWM Kanäle des Shields mal an 5V gelegt statt an GND?

Was meinst du mit

Leider sagt der kontroller garnichts

Hast du es angeschlossen wie auf dem Bild:

Die PWMs musst du wie gesagt mal auf +5V oder GND legen
Anstatt pin 9 und 10 nimmst du die, die du nehmen willst :wink:
(Sorry für die Optik, habe es schnell mit Paint gemacht)

Hast du alle Jumper vom Shield entfernt, falls du welche drauf hast?

Hallo,
erstmal Danke für die tolle Hilfe!!
Ich bin Zeitlich z.Zt. etwas eingeschränkt, deshalb erstmal einpaar Fragen zwischen durch.

Wie werden die Freilaufdioden angeschlossen ?
Und kann ich die 1N4001 dafür nehmen ?

Habe gerade gelesen das die Freilaufdioden schon integriert sind...

@Addi2438, werden die folgenden Pins alle an GND angeschlossen ?

SF
FB
SLEW
INV

Vielen Dank

In meinem "Schaltplan" schon, sry habe das vergessen hinzuschreiben :D.
Laut Website sind das Statuspins (außer INV), die du nutzen kannst um "Infos" zu bekommen.
Da es dir erst nur darum geht die Motoren zum Laufen zu kriegen kannst du die einfach an GND des Arduinos anschließen.

GND auf der Motorseite des Boards entsprich dem Minuspol deiner Spannungsquelle für den Motor.
VIN auf der Motorseite des Boards entspricht dem Pluspol

Edit:
Hast du Jumper auf dem Board? Wenn ja, dann musst du die entfernen.

PWM schließt du an 5V des Arduinos an, wenn sich da dann nix tut, schließe sie mal an GND vom Arduino

Addi2438:
...
Edit:
Hast du Jumper auf dem Board? Wenn ja, dann musst du die entfernen.
...

Nein, sind keine Jumper vorhanden...

So, ich habe nun alles fertig gelötet und angeschlossen, aber es funktioniert nicht zu meiner zufriedenheit :blush:
Besser gesagt es funktioniert garnicht.
Der Motor wird ca 2x hin oder her geschaltet, dann schaltet der MC33926 die "over-current Protection" ein und
es sind beide Motorausgänge auf +12V geschaltet.

Was ich aber nicht verstehe, denn auf dem Motor steht Max 3A und der MC33926 verkraftet laut Datenblatt 5A...

Was kann ich anders machen ? Weiß jemand Rat ?
Ich werde heute abend mal Skizzieren, wie ich alles angeschlossen habe.
Es muss doch möglich sein, einen Solartracker mit Arduino zu realisieren.
Mit einen Linearmotor statt wie überall beschrieben, mit einem Steppermotor...

Der Motor wird ca 2x hin oder her geschaltet, dann schaltet der MC33926 die "over-current Protection" ein und
es sind beide Motorausgänge auf +12V geschaltet.

Da sich der Motor zuerst dreht, liegt das wohl an der Software.
Wenn du beide Inputs des Boards auf HIGH schaltest und das kann an einer Stelle im Programm passieren, dann gehen auch beide Outputs auf HIGH, daher schließt du den Motor kurz. Hast du mal überprüft, ob beide Inputs auch auf HIGH sind?

else if (left == rightN)                          // sind links u. rechts gleich, in dieser stellung für 30 sek. bleiben
    {
      pauseMillis = millis();
      //Serial.println(F("Horizontal Optimal !"));
      digitalWrite(moveleft, HIGH);
      digitalWrite(moveright, HIGH);
      lcd.setCursor(14,1);
      lcd.write(2);
      }

Ändere das mal auf LOW, dann bleibt der Motor auch in seiner Position.

Versuch doch zunächst mal den Motor nur über ein ganz simples Programm zu steuern. Indem du einfach nur einen der beiden Inputs auf HIGH setzt.

Addi2438:

Der Motor wird ca 2x hin oder her geschaltet, dann schaltet der MC33926 die "over-current Protection" ein und
es sind beide Motorausgänge auf +12V geschaltet.

Da sich der Motor zuerst dreht, liegt das wohl an der Software.

Ok, vieleicht habe ich mich verkehrt ausgedrückt.

Der Sketch läuft, die LDR´s werden abgefragt und dann wird geschaltet, LINKS oder RECHTS.
Und das macht er ca 2-3x dann sind auf beiden Ausgängen +12V messbar.

Also us dem Datenblatt erlese ich, das er abschaltet, wegen "over-current Protection" .

Wenn du beide Inputs des Boards auf HIGH schaltest und das kann an einer Stelle im Programm passieren, dann gehen auch beide Outputs auf HIGH, daher schließt du den Motor kurz. Hast du mal überprüft, ob beide Inputs auch auf HIGH sind?

else if (left == rightN)                          // sind links u. rechts gleich, in dieser stellung für 30 sek. bleiben

{
      pauseMillis = millis();
      //Serial.println(F("Horizontal Optimal !"));
      digitalWrite(moveleft, HIGH);
      digitalWrite(moveright, HIGH);
      lcd.setCursor(14,1);
      lcd.write(2);
      }




Ändere das mal auf LOW, dann bleibt der Motor auch in seiner Position.

Das hatte ich schon gemacht, alles angepasst.
Ich hänge den jetzigen Sketch nochmal an.

Versuch doch zunächst mal den Motor nur über ein ganz simples Programm zu steuern. Indem du einfach nur einen der beiden Inputs auf HIGH setzt.

Ok, werde ich machen ...

Sketch

Also, ich habe jetzt mal nachgemessen.
Der Motor zieht laut meinem Multimeter 0,7A
Das dürfte wohl nicht das Problem sein :~

Ich habe alles wie folgt verkablet:

Arduino Nano --- > MC33926

  • 5V ---> EN (Pin10)
    GND ---> GND (Pin2)
    GND ---> D1 (pin7)
    Pin 4 ---> IN1(Pin5)
    Pin 5 ---> IN2(Pin4)
  • 5V ---> D2(Pin 6)

Hier mal 2 Bilder vom Aufbau :

INV musst du auch an GND anschließen.

Hast du mal überprüft, welchen Pegel die beiden In-Eingänge haben, nachdem beide Motorausgänge auf HIGH geschaltet worden sind?

Hallo,
werde ich nachher, wenn ich zuhause bin testen...
Danke.. :smiley:

ich habe nochmal eine Verständnis Frage, weil mein Englisch grotten schlecht ist.
Also in der Beschreibung steht folgendes drin:

The fault-status (FS, active low) output pin may be left disconnected if you do not want to monitor the fault conditions of the motor driver; if you do connect it you must use an external pull-up resistor to pull the line high

Heißt das, wenn ich den Fehler-Status abschalten möchte, muss ich einen "Pull-Up-Widerstand" auf +5V legen ?

Habe ich das richtig verstanden ?
Wenn ja, wieviel Ohm hat denn der Widerstand ?

Vielen Dank für Eure Hilfe...

Nein. Unbenutzt ist er offen. Benutzt braucht er einen Pullup. Mit anderen Worten, es ist ein Open Collector/Drain Ausgang.

Abschalten kannst du da nichts. Entweder man werter den Fehler Status aus oder nicht.

mmhh. OK. Danke.
Dann verstehe ich mein Problem nicht...

ALso, ich versuche es mal zu erklären.
Der Motor bewgt sich den ganzen Tag immer weiter in eine Richtung, wenn er dann am Ende angekommen ist, schaltet der Motorendschalter.
Und es passiert folgendes, der Motor wird nicht mehr zurrück bewegt, wenn die LDR´s es sagen.
Genauso ist es, wenn ich einen Stecker vom Motor abziehe, wenn er sich gerade bewegt und ich ihn dann wieder reinstecke.
Es wird nichts mehr geschaltet.

Durch zufall bzw. ausversehen, habe ich Pin EN, der ja +5V hat, und Pin FB mit einander kurz verbunden und siehe da, alles läuft wieder ?

Weiß jemand vieleicht warum das so ist ? bzw. muss/soll ich den Pin FB auch auf +5V legen ?

Oder weiß jemand warum das Passiert, das es stehen bleibt ?

Bin ziemlich ratlos. Angeschlossen habe ich den MC33926 wie folgt:
Arduino Nano --- > MC33926

  • 5V ---> EN (Pin10)
    GND ---> GND (Pin2)
    GND ---> D1 (pin7)
    Pin 4 ---> IN1(Pin5)
    Pin 5 ---> IN2(Pin4)
  • 5V ---> D2(Pin 6)
    GND ---> INV(Pin12)

Oder muss D1(Pin7) auch auf +5V gesetzt werden ?
Ich benutze kein PWM
Ich werde aus dieser Beschreibung nicht schlau.. :blush: