Hi
Ich habe die Schaltung mit dem RNST01 zur Ansteuerung von 2 Schrittmotoren nachgebaut.(Von robotikhardware.de) Die Platine ist auf meinem Roboter verbaut der zusätzlich mit einer Sensorplatine bestückt ist. An die Sensorplatine sind 3 Distanzsensoren angeschlossen. Die 3 Sensorwerte werden mit Hilfe eines AD-Wandlers PCF-8591 ausgelesen.
Angesteuert wird das ganze über nen RS232 Dongle nach I2C. Die Ansteuerung der Sensorwerte macht keine Probleme. Die läuft wirklich sehr gut. Nur bei der Ansteuerung der Schrittmotoren tut sich nichts. Es muss irgendwas noch in meinem Quellcode falsch sein , dass die Ansteuerung nicht funktioniert. Ein HardwareFehler kann ich ausschließen hab die Platine sehr genau überprüft. Ich habe auch ein Terminal mit nem max232 an die Schaltung angeschlossen. Sobald die Platine mit Spannung versorgt wird initialisiert sie etc... Nur wenn ich nun Signale an den RNST01 sende passiert nichts. Die Treiberbausteine(L29bleiben immer kalt. Könntet ihr bitte einen Blick auf meinen Quellcode werfen.
Im Quellcode mit eingebunden ist die port.dll und die i2c.com zum öffnen des Com-Ports und die I2C Befehle.
Quellcode des Programms:
I2c.com:Code:unit RNST01_Form; interface uses I2CCOM,PORTINC, SysUtils, Classes, Graphics, Controls, Forms, ExtCtrls, StdCtrls, LMDCustomButton, LMDButton, LMDControl, LMDBaseControl, LMDBaseGraphicControl, LMDGraphicControl, LMDBaseMeter, LMDCustomProgressFill, LMDProgressFill, Buttons; const RNST01_Write:byte = $56; RNST01_Read :byte = $57; cActivityInd:array[0..3] of char = ('\','|','/','-'); type TForm1 = class(TForm) Timer1: TTimer; Panel3: TPanel; comboPort: TComboBox; btnStartStop: TLMDButton; Label7: TLabel; comboSpeed: TComboBox; Label8: TLabel; IndTimer: TLMDProgressFill; IndSDA: TLMDProgressFill; IndSCL: TLMDProgressFill; btnISet: TButton; Edit1: TEdit; Label1: TLabel; Label2: TLabel; Label3: TLabel; Label4: TLabel; Label5: TLabel; Label6: TLabel; btnMotorLinksDrehtLinks: TSpeedButton; btnMotorLinksDrehtRechts: TSpeedButton; Label9: TLabel; Label10: TLabel; btnMotorRechtsDrehtRechts: TSpeedButton; btnMotorRechtsDrehtLinks: TSpeedButton; Label15: TLabel; SpeedButton5: TSpeedButton; btnVoll: TSpeedButton; btnHalb: TSpeedButton; Panel1: TPanel; SpeedButton3: TSpeedButton; SpeedButton4: TSpeedButton; Label13: TLabel; Label11: TLabel; SpeedButton2: TSpeedButton; SpeedButton1: TSpeedButton; Label12: TLabel; Label17: TLabel; Label16: TLabel; Label18: TLabel; Edit2: TEdit; Button1: TButton; SpeedButton6: TSpeedButton; Button2: TButton; procedure Timer1Timer(Sender: TObject); procedure btnStartStopClick(Sender: TObject); procedure btnISetClick(Sender: TObject); procedure btnVollClick(Sender: TObject); procedure btnHalbClick(Sender: TObject); procedure btnMotorLinksDrehtLinksClick(Sender: TObject); procedure btnMotorLinksDrehtRechtsClick(Sender: TObject); procedure btnMotorRechtsDrehtLinksClick(Sender: TObject); procedure btnMotorRechtsDrehtRechtsClick(Sender: TObject); procedure btnMotorenAnClick(Sender: TObject); procedure Button1Click(Sender: TObject); procedure SpeedButton1Click(Sender: TObject); procedure SpeedButton4Click(Sender: TObject); procedure SpeedButton2Click(Sender: TObject); procedure SpeedButton3Click(Sender: TObject); procedure SpeedButton6Click(Sender: TObject); procedure SpeedButton5Click(Sender: TObject); procedure Button2Click(Sender: TObject); end; var Form1: TForm1; ActivityInd:integer; implementation uses Dialogs; {$R *.DFM} procedure TForm1.Timer1Timer(Sender: TObject); begin IndTimer.Caption:=cActivityInd[ActivityInd]; inc(ActivityInd,1); if ActivityInd>=4 then ActivityInd:=0; Application.ProcessMessages; // REALTIME(false); // DELAYUS(100); // REALTIME(false); IndSDA.UserValue:=Integer(DSR); IndSCL.UserValue:=Integer(CTS); end; procedure TForm1.btnStartStopClick(Sender: TObject); begin ActivityInd:=0; if btnStartStop.Caption='Start' then begin btnStartStop.Caption:='Stop'; I2C_Init(ComboPort.ItemIndex+1,StrToInt(ComboSpeed.Text)); IndTimer.Enabled:=true; IndTimer.Caption:=''; IndSDA.Enabled:=true; IndSCL.Enabled:=true; Timer1.Enabled:=true; end else begin Timer1.Enabled:=false; btnStartStop.Caption:='Start'; I2C_DeInit(-1); IndTimer.Enabled:=false; IndTimer.Caption:='Timer'; IndSDA.Enabled:=false; IndSCL.Enabled:=false; IndSDA.UserValue:=0; IndSCL.UserValue:=0; end; end; procedure TForm1.btnISetClick(Sender: TObject); var Strom:Integer; begin Strom:=StrToIntDef(Edit1.Text,-1) div 10; if Strom=-1 then MessageDlg(format('Strom: ungültiger Wert "%s" mA',[Edit1.Text]), mtWarning, [mbOK], 0) else begin REALTIME(true); I2C_Start; I2C_Write(RNST01_Write); I2C_Acknowledge(noAck); I2C_Write(10); //Kennung RNST01 I2C_Acknowledge(noAck); I2C_Write(1); //Befehl: Motorstrom setzen I2C_Acknowledge(noAck); I2C_Write(2); //Kennung: beide Motoren I2C_Acknowledge(noAck); I2C_Write(Strom); I2C_Acknowledge(noAck); I2C_Stop; REALTIME(false); end; end; procedure TForm1.btnVollClick(Sender: TObject); begin REALTIME(true); I2C_Start; I2C_Write(RNST01_Write); I2C_Acknowledge(noAck); I2C_Write(10); //Kennung RNST01 I2C_Acknowledge(noAck); I2C_Write(14); //Befehl: Voll-/Halbschritt Modus wählen I2C_Acknowledge(noAck); I2C_Write(0); //Beide Motoren Vollschritt Modus I2C_Acknowledge(noAck); I2C_Stop; REALTIME(false); end; procedure TForm1.btnHalbClick(Sender: TObject); begin REALTIME(true); I2C_Start; I2C_Acknowledge(noAck); I2C_Write(RNST01_Write); I2C_Acknowledge(noAck); I2C_Write(10); //Kennung RNST01 I2C_Acknowledge(noAck); I2C_Write(14); //Befehl: Voll-/Halbschritt Modus wählen I2C_Acknowledge(noAck); I2C_Write(1); //Beide Motoren Halbschritt Modus I2C_Acknowledge(noAck); I2C_Stop; REALTIME(false); end; procedure TForm1.btnMotorLinksDrehtLinksClick(Sender: TObject); begin REALTIME(true); I2C_Start; I2C_Acknowledge(noAck); I2C_Write(RNST01_Write); I2C_Acknowledge(noAck); I2C_Write(10); //Kennung RNST01 I2C_Acknowledge(noAck); I2C_Write(4); //Befehl: Motor Drehrichtung I2C_Acknowledge(noAck); I2C_Write(0); //Linker Motor I2C_Acknowledge(noAck); I2C_Write(0); //Drehe Links I2C_Acknowledge(noAck); I2C_Stop; REALTIME(false); end; procedure TForm1.btnMotorLinksDrehtRechtsClick(Sender: TObject); begin REALTIME(true); I2C_Start; I2C_Write(RNST01_Write); I2C_Acknowledge(noAck); I2C_Write(10); //Kennung RNST01 I2C_Acknowledge(noAck); I2C_Write(4); //Befehl: Motor Drehrichtung I2C_Acknowledge(noAck); I2C_Write(0); //Linker Motor I2C_Acknowledge(noAck); I2C_Write(1); //Drehe Rechts I2C_Acknowledge(noAck); I2C_Stop; REALTIME(false); end; procedure TForm1.btnMotorRechtsDrehtLinksClick(Sender: TObject); begin REALTIME(true); I2C_Start; I2C_Write(RNST01_Write); I2C_Acknowledge(noAck); I2C_Write(10); //Kennung RNST01 I2C_Acknowledge(noAck); I2C_Write(4); //Befehl: Motor Drehrichtung I2C_Acknowledge(noAck); I2C_Write(1); //Rechter Motor I2C_Acknowledge(noAck); I2C_Write(0); //Drehe Links I2C_Acknowledge(noAck); I2C_Stop; REALTIME(false); end; procedure TForm1.btnMotorRechtsDrehtRechtsClick(Sender: TObject); begin REALTIME(true); I2C_Start; I2C_Write(RNST01_Write); I2C_Acknowledge(noAck); I2C_Write(10); //Kennung RNST01 I2C_Acknowledge(noAck); I2C_Write(4); //Befehl: Motor Drehrichtung I2C_Acknowledge(noAck); I2C_Write(1); //Rechter Motor I2C_Acknowledge(noAck); I2C_Write(1); //Drehe Rechts I2C_Acknowledge(noAck); I2C_Stop; REALTIME(false); end; procedure TForm1.btnMotorenAnClick(Sender: TObject); begin REALTIME(true); I2C_Start; I2C_Write(RNST01_Write); I2C_Acknowledge(noAck); I2C_Write(10); //Kennung RNST01 I2C_Acknowledge(noAck); I2C_Write(10); //Befehl: Motor Kontrolle I2C_Acknowledge(noAck); I2C_Write(2); //Beide Motoren einschalten I2C_Acknowledge(noAck); I2C_Stop; REALTIME(false); end; procedure TForm1.Button1Click(Sender: TObject); var Schrittwert:Integer; begin Schrittwert:=StrToIntDef(Edit2.Text,-1) ; if (Schrittwert<0) or (Schrittwert>255) then MessageDlg(format('Schritte: ungültiger Wert "%s"´. Wert muss zwischen 0 und 255 liegen' ,[Edit2.Text]), mtWarning, [mbOK], 0) else begin REALTIME(true); I2C_Start; I2C_Write(RNST01_Write); I2C_Acknowledge(noAck); I2C_Write(10); //Kennung RNST01 I2C_Acknowledge(noAck); I2C_Write(8); //Befehl: Schritte pro Sekunde I2C_Acknowledge(noAck); I2C_Write(2); //Beide Motoren I2C_Acknowledge(noAck); I2C_Write(SchrittWert); I2C_Acknowledge(noAck); I2C_Stop; REALTIME(false); end; end; procedure TForm1.SpeedButton1Click(Sender: TObject); begin REALTIME(true); I2C_Start; I2C_Write(RNST01_Write); I2C_Acknowledge(noAck); I2C_Write(10); //Kennung RNST01 I2C_Acknowledge(noAck); I2C_Write(6); //Befehl: Motor einschalten I2C_Acknowledge(noAck); I2C_Write(0); //Linker Motor I2C_Acknowledge(noAck); I2C_Stop; REALTIME(false); end; procedure TForm1.SpeedButton4Click(Sender: TObject); begin REALTIME(true); I2C_Start; I2C_Write(RNST01_Write); I2C_Acknowledge(noAck); I2C_Write(10); //Kennung RNST01 I2C_Acknowledge(noAck); I2C_Write(6); //Befehl: Motor einschalten I2C_Acknowledge(noAck); I2C_Write(1); //Rechter Motor I2C_Acknowledge(noAck); I2C_Stop; REALTIME(false); end; procedure TForm1.SpeedButton2Click(Sender: TObject); begin REALTIME(true); I2C_Start; I2C_Write(RNST01_Write); I2C_Acknowledge(noAck); I2C_Write(10); //Kennung RNST01 I2C_Acknowledge(noAck); I2C_Write(3); //Befehl: Motor stoppen, Strom eingeschaltet lassen I2C_Acknowledge(noAck); I2C_Write(0); //Linker Motor I2C_Acknowledge(noAck); I2C_Stop; REALTIME(false); end; procedure TForm1.SpeedButton3Click(Sender: TObject); begin REALTIME(true); I2C_Start; I2C_Write(RNST01_Write); I2C_Acknowledge(noAck); I2C_Write(10); //Kennung RNST01 I2C_Acknowledge(noAck); I2C_Write(3); //Befehl: Motor stoppen, Strom eingeschaltet lassen I2C_Acknowledge(noAck); I2C_Write(1); //Linker Motor I2C_Acknowledge(noAck); I2C_Stop; REALTIME(false); end; procedure TForm1.SpeedButton6Click(Sender: TObject); begin Panel1.Enabled:=false; Panel1.Color:=clBackground; REALTIME(true); I2C_Start; I2C_Write(RNST01_Write); I2C_Acknowledge(noAck); I2C_Write(10); //Kennung RNST01 I2C_Acknowledge(noAck); I2C_Write(9); //Befehl: Motor Kontrolle - Strom aus I2C_Acknowledge(noAck); I2C_Write(2); //Beide Motoren ausschalten I2C_Acknowledge(noAck); I2C_Stop; REALTIME(false); end; procedure TForm1.SpeedButton5Click(Sender: TObject); begin Panel1.Enabled:=true; Panel1.Color:=clBtnFace; REALTIME(true); I2C_Start; I2C_Write(RNST01_Write); I2C_Acknowledge(noAck); I2C_Acknowledge(noAck); I2C_Write(10); //Kennung RNST01 I2C_Acknowledge(noAck); I2C_Write(10); //Befehl: Motor Kontrolle - Strom ein I2C_Acknowledge(noAck); I2C_Write(2); //Beide Motoren einschalten I2C_Acknowledge(noAck); I2C_Stop; REALTIME(false); end; procedure TForm1.Button2Click(Sender: TObject); begin REALTIME(true); I2C_Start; I2C_Write(RNST01_Write); I2C_Acknowledge(noAck); I2C_Write(10); //Kennung RNST01 I2C_Acknowledge(noAck); I2C_Write(11); //Befehl: Konfiguration anzeigen I2C_Acknowledge(noAck); I2C_Stop; REALTIME(false); end; end.
Ich denke das es vielleicht auch an der i2c.com liegen könnte . Das die Routine einfach nicht richtig stimmt.Code://Purpose : I2C BitBanging routines for the serial ports using the PORT.DLL //Reason : I2C_DeInit added. This is for a defined close of the I2C // communication after use (for example when terminating an // application) // Renamed all procedures and function to meet the english language. // Also set the prefix "I2C_" in front of each procedure/function to // avoid possible conflicts with other procedures/functions with a // similar name. unit I2CCOM; {______________________________________________________________________________} interface uses SysUtils, StrUtils, PORTINC; const ack :boolean=true; noack:boolean=false; delayMarker:Cardinal=1; procedure I2C_Init(ComPort:Integer; Baud:Integer); procedure I2C_DeInit(ComPort:Integer); Procedure I2C_Start; Procedure I2C_Stop; Procedure I2C_Acknowledge(ack:boolean); Function I2C_Write (Wert : Byte): Boolean; Function I2C_Read : Byte; overload; Function I2C_Read(dummy:string) : string; overload; procedure SDA(Value:byte); overload; function SDA:byte; overload; procedure SCL(Value:byte); overload; function SCL:byte; overload; {______________________________________________________________________________} implementation uses DateUtils; type eTimeOutError=class(Exception); var sTime,eTime:TDateTime; TimeoutValue:integer; DelayValue:cardinal; function isTimeout(what:string):boolean; begin Result:=SecondsBetween(sTime,eTime)>=TimeoutValue; if Result then Raise eTimeOutError.CreateFmt('I2C Timeout (%s)',[what]); end; procedure SDA(Value:byte); overload; begin DTR(Value); end; function SDA:byte; overload; begin Result:=DSR; end; procedure SCL(Value:byte); overload; begin RTS(Value); // if Value=0 then // repeat // Delayus(DelayValue); // eTime:=now; // until (SCL=0) or isTimeout('SCL=0'); repeat Delayus(DelayValue); eTime:=now; until (SCL=Value) or isTimeout('SCL='+IntToStr(Value)); end; function SCL:byte; overload; begin Result:=CTS; end; procedure I2C_Init(ComPort:Integer; Baud:Integer); begin OpenCom(Pchar(format('com%d:%d,N,8,1',[ComPort,Baud]))); I2C_Stop; Delayus(DelayValue); end; procedure I2C_DeInit(ComPort:Integer); begin I2C_Stop; CloseCom; end; procedure I2C_Start; begin SCL(1); Delayus(DelayValue); SDA(1); sTime:=now; repeat Delayus(DelayValue); eTime:=now; until (SCL=1) and (SDA=1) or isTimeout('Start'); SDA(0); Delayus(DelayValue); SCL(0); Delayus(DelayValue); end; procedure I2C_Stop; begin SDA(0); Delayus(DelayValue); SCL(1); sTime:=now; repeat Delayus(DelayValue); eTime:=now; until (SCL=1) or isTimeout('Stop'); SDA(1); Delayus(delayMarker*DelayValue); end; procedure I2C_Pulse; begin SCL(1); sTime:=now; repeat Delayus(DelayValue); eTime:=now; until (SCL=1) or isTimeout('Pulse'); SCL(0); Delayus(DelayValue);//new end; procedure I2C_Acknowledge(ack:boolean); begin if ack then begin SDA(0); Delayus(DelayValue); I2C_Pulse; end else begin SDA(1); Delayus(DelayValue); I2C_Pulse; end; Delayus(delayMarker*DelayValue); end; Function I2C_Write(Wert : Byte): Boolean; var Bitwert, n: Byte; begin Result := true; Bitwert := 128; //SDA(0); for n:= 1 to 8 do begin if (Wert and Bitwert) = Bitwert then SDA(1) else SDA(0); Bitwert := Bitwert SHR 1; Delayus(DelayValue); I2C_Pulse; end; // Delayus(DelayValue); // I2C_Pulse; Delayus(delayMarker*DelayValue); end; function I2C_Read : Byte; var Mask, n: Byte; begin SDA(1); Mask := 128; Result := 0; for n:= 1 to 8 do begin SCL(1); sTime:=now; repeat Delayus(DelayValue); eTime:=now; until (SCL=1) or isTimeout('Read'); if SDA=1 then Result := Result OR Mask ; Mask := Mask SHR 1; SCL(0); Delayus(DelayValue); end; end; Function I2C_Read(dummy:string) : string; overload; var Mask, n: Byte; begin SDA(1); Mask := 128; Result:=''; for n:= 1 to 8 do begin SCL(1); sTime:=now; repeat Delayus(DelayValue); eTime:=now; until (SCL=1) or isTimeout('Read'); Result:=Result+ifthen(SDA=1,'1','0'); Mask := Mask SHR 1; SCL(0); Delayus(DelayValue); end; end; {______________________________________________________________________________} initialization TimeoutValue:=3; //seconds DelayValue :=1; //microseconds end.
Wär spitze wenn ihr mir weiterhelfen könntet.
Gruß Nero
Lesezeichen