nrComm cannot communication with Arduino that use CH340G Chip but Comport can do

Started by amit, January 04, 2020, 01:17:09 pm

Previous topic - Next topic

amit

Hi,

I have two Arduino Uno boards.  One from original Arduino Italy and another one is a compatible from China.
I programmed both boards to send the data back to host computer when it received string "#01"+CR.  I found that I cannot communicate with China made Arduino Uno that use CH340G chip for Serial communication but it can work with original Arduino Uno made from Italy.   So I use TeraTerm to test both boards especially the china made one and found both boards works as they should be.   So I replace nrComm component with Winsoft Comport to test them again.  It works fine for both boards.   I don't understand why nrComm cannot do the job.   Here is the Delphi code using nrComm and Next using Winsoft Comport.     Please help to find out the reason and fix this problem for me.

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, nrclasses, nrcomm, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    nrComm1: TnrComm;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Button1Click(Sender: TObject);
    procedure nrComm1AfterReceive(Com: TObject; Buffer: Pointer;
      Received: Cardinal);
  private
    { Private declarations }
    DataPacket:Ansistring;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  nrComm1.SendString('#01'+#13);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  nrComm1.Active:=false;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  nrComm1.Active:=true;
end;

procedure TForm1.nrComm1AfterReceive(Com: TObject; Buffer: Pointer;
  Received: Cardinal);
var i:integer;
    ch:AnsiChar;
begin
  for i := 0 to Received - 1 do
  begin
    ch := PAnsiChar(Buffer)[I];
    if ch = #13 then
    begin
      memo1.Lines.Add(DataPacket);
      DataPacket:='';
    end else
    begin
      DataPacket := DataPacket + ch;
    end;
  end;
end;

end.

Here is Winsoft Comport Code.
unit Unit2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, ComPort, Vcl.StdCtrls;

type
  TForm2 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    ComPort1: TComPort;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Button1Click(Sender: TObject);
    procedure ComPort1RxFlag(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
begin
  Comport1.WriteAnsiString('#01'+#13);
end;

procedure TForm2.ComPort1RxFlag(Sender: TObject);
begin
  memo1.Lines.Add(Comport1.ReadAnsiUntil(#13));
end;

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Comport1.Close;
end;

procedure TForm2.FormCreate(Sender: TObject);
begin
  Comport1.Open;
end;

end.


Roman Novgorodov

Hello

Possible something is wrong with default serial port communication settings or port initialization.

You can try to set something like that:

procedure TForm1.FormShow(Sender: TObject);
begin
  nrComm1.BaudRate := 9600;
  nrComm1.StreamProtocol := spNone;
  nrComm1.TraceStates := [tsRxChar];
  nrComm1.Active:=true;
end;

Roman Novgorodov
DeepSoftware llc
DeepSoftware llc - The professional components for Delphi/CBuilder/.NET. The high quality custom software development.
Forums.nrCommLib.Com - DeepSoftware Tech Support Forum.

amit

Quote from: Roman Novgorodov on January 05, 2020, 08:08:18 amHello

Possible something is wrong with default serial port communication settings or port initialization.

You can try to set something like that:

procedure TForm1.FormShow(Sender: TObject);
begin
  nrComm1.BaudRate := 9600;
  nrComm1.StreamProtocol := spNone;
  nrComm1.TraceStates := [tsRxChar];
  nrComm1.Active:=true;
end;

Roman Novgorodov
DeepSoftware llc

Thank you for your help.  IT'S WORKING NOW  after follow your suggestion.    By the way, can you give me some explanation on

  StreamProtocol := spNone;
  TraceStates := [tsRxChar]

And why it's working on the original Arduino Uno before changing the code.

Roman Novgorodov

Hello

I can not explain that exactly.

You just need to understand that CH3xxx chips have specific features in
hardware and driver implementations.
And possible nrComm Lib does something wrong with CHxxx and additional initialization is needed.

In your case you can comment out some lines of my code and find one that fixes problem exactly.
And set it at design time and check. Possible additional run time code can be removed.

Details:
StreamProtocol := spNone;
This line turns off Hardware or Software stream control protocols.

TraceStates := [tsRxChar]
This flag is necessary for raising nrComm1AfterReceive handler.

Please note that several years ago chinas CHxxx chips had real problems. You can get BSOD after restarting PC or enter in to sleep mode. Possible such problems are gone now. Anyway we prefer to use Moschip, Prolific well know brands.

Roman Novgorodov
DeepSoftware llc - The professional components for Delphi/CBuilder/.NET. The high quality custom software development.
Forums.nrCommLib.Com - DeepSoftware Tech Support Forum.


amit

I switch to use Arduino Mega 2560 Board with CH340G chip and I found same problem even I put the code you suggested.
 
  nrComm1.BaudRate := 9600;
  nrComm1.StreamProtocol := spNone;
  nrComm1.TraceStates := [tsRxChar];
  nrComm1.Active:=true;

After try to find out what is the cause of this problem and I finally found that if I put the delay about 750 ms after set nrComm1 Active the problem gone.  In my code after open the port I send out the data to the port immediately this may caused the problem.  Is it possible that nrComm Lib does not check any ready flag or something and it returns too fast. So the Sendstring command that immediately call while the port is not yet successfully opened may cause of the problem.      Please investigate because if I use Comport this problem never occurred.   By the way, nrComm1.StreamProtocol := spNone; is also needed if it is not spNone it won't work. 

Roman Novgorodov

Hello

Thank you for information.

I told you that problem is in driver implementation of CHxxx chip.
It returns success handle of serial port without finish the correct intitiallization.
Other chips from other brands do not have such problem.

Possible we will include a delay after serial port open in the next version.

Roman Novgorodov
DeepSoftware llc - The professional components for Delphi/CBuilder/.NET. The high quality custom software development.
Forums.nrCommLib.Com - DeepSoftware Tech Support Forum.