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(L29 bleiben 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:
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.
I2c.com:


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.
Ich denke das es vielleicht auch an der i2c.com liegen könnte . Das die Routine einfach nicht richtig stimmt.

Wär spitze wenn ihr mir weiterhelfen könntet.

Gruß Nero