Bluetooth-Arduino

Odpovědět
haas

Bluetooth-Arduino

Příspěvek od haas »

Dobrý den,
mám arduino uno a bluetooth obs 410i.Přenos je nastaven 9600bd 8datových bitů,bez parity,1stop bit .Zkoušel jsem spojit pc s arduinem přes bluetooth pomocí terminálu tank control http://pandatron.cz/?740&robot_ovladany_pres_bluetooth a pidibot http://www.micovo.cz/robotika-pidibot.htm které jsem našel na internetu.
Příchozí znaky do arduina jsou v ascii kodu.Nevím jak vytvořit podmínku v programu arduina, aby arduino poznalo co má udělat.

Můžete mi poradit jak zprávně zpracovávat příjmané data?Idyž z terminálu tank control přímo přes řádek send pošlu třeba číslo 20 tak arduino mi na lcd zobrazí úplně jiná čísla.
Vkládám i jednoduchý program pro výpis přijatých dat v desítkové a binární soustavě.Byl bych vděčný za jakoukoliv pomoc.


Kód: Vybrat vše

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
int val;
int sloupec=0;

LiquidCrystal_I2C lcd(0x27,16,2);

void setup()
{ lcd.init(); 
  lcd.backlight();
  lcd.setCursor(0,0);
  Serial.begin(9600); 
}

void loop()   {

if (Serial.available()){ 
   val = Serial.read();
 
   
    lcd.setCursor(0,0);
    lcd.print(val,BIN);
    lcd.setCursor(0,1);
    lcd.print(val,DEC);
    delay(10);  
    }
}
Přílohy
IMG481.jpg
IMG482.jpg
hubacekp
Příspěvky: 259
Registrován: 24 úno 2013, 13:40

Re: Bluetooth-Arduino

Příspěvek od hubacekp »

Ahoj,

0) připoj si arduino nejdříve přes USB kabel a rozchoď si to bez BT.
1) pokud chceš znaky i zobrazovat, tak "int val"; bys mohl změnit na "char val"; -- přijímáš nejprve "2" a potom "0"
pro info: zobrazilo se ti někdy 5048 místo těch 20? char 2 = dec 50 a char 0 = dec 48
2) pokud to display bezpodmínečně nevyžaduje, odstraň delay(10);
3) to co přijmeš na arduinu hned pošli pro kontrolu zpět jako echo:
val = Serial.read();
Serial.print(val);
4) změň DEC v lcd.print(val,DEC); na formát dat, která zpracováváš. Mohlo by to být jen lcd.print(val); ?
5) pro testování můžeš použít i terminál HERKULES
- pro základní debug je Herkules ideální a můžeš v něm později testovat na jiném projektu i HTTP requesty

Hodně štěstí
haas

Re: Bluetooth-Arduino

Příspěvek od haas »

Tak jsem změnil int val na char val a zobrazovali se nějaké klikyháky.Po odeslání čísla 20 se zobrazilo 50 pak 48.Odstranění delay nepomůže.Zkoušel jsem odesílat data zpět z arduina do pc a je to stejné.Všechno co tank control posílá je v ascii.
Odstranění DEC ze závorky jsem zkoušel jako první.I tak se vše zobrazuje v DEC.Pro ten Herkules ale musím mít na pc com,ne?Já žádný com nemám(mám notebook).¨

Jinak jsem si naistaloval delphi 7 a prozkoumal jsem kod.našel jsem řádky, kde bylo psáno FF (levý pravý motor forward)BB.... tak jsem to přepsal na čísla 0 až 4, ale pořád to posílá původní text.Ještě za každým odeslaným příkazem se automaticky odešle číslo 13 a 10.V kodu jsou definovány jako chr(10) chr (13) a ty v arduinu opravdu přijmu jako číslo 10 a 13. Zkoušel jsem tedy stejně definovat i ostaní proměné ale neuspěšně.
Podle mě je tam někde definováno, že vše co se odesílá je jako text.

Nevíte jak upravit kod aby to posílalo čísla ne text.Vyznáte se v delpi.Prosím jestli můžete poraďte.Díky.

Pokud stisku tlačítko Forward příjmu postupně 70,13,10 Stop 83,13,10 Backward 66,13,10 Left 70,66, 13,10 Right 66,70,13,10


Přikádám původní zdrojový kod:
Jedná se o písmena SS,FF,FB,BF,BB.
Proměnná command je typu TEdit není tohle definice textu?

Kód: Vybrat vše

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  SynaSer, StdCtrls, ExtCtrls, Menus, Unit2;

type
  TForm1 = class(TForm)
    GroupBox1: TGroupBox;
    comName: TEdit;
    baudrate: TEdit;
    connectButton: TButton;
    Label4: TLabel;
    Label5: TLabel;
    GroupBox2: TGroupBox;
    Memo1: TMemo;
    Forward: TButton;
    Stop: TButton;
    disconnectButton: TButton;
    Backward: TButton;
    Right: TButton;
    Left: TButton;
    MainMenu1: TMainMenu;
    xzcxzcxz: TMenuItem;
    Exit1: TMenuItem;
    GroupBox3: TGroupBox;
    command: TEdit;
    sendButton: TButton;
    About1: TMenuItem;
    procedure connectButtonClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure ForwardClick(Sender: TObject);
    procedure StopClick(Sender: TObject);
    procedure disconnectButtonClick(Sender: TObject);
    procedure LeftClick(Sender: TObject);
    procedure RightClick(Sender: TObject);
    procedure BackwardClick(Sender: TObject);
    procedure Exit1Click(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure sendButtonClick(Sender: TObject);
    procedure About1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  connected: boolean;
  ser: TBlockSerial;
  stopped: boolean;

const
  APP_VERSION = 'v1.0';

implementation

{$R *.DFM}

(**
 * sends command to serial port
 *)
procedure sendCommand(command: string);
begin
  if (command = 'SS') then begin
    stopped := true;
  end else begin
    stopped := false;
  end;

  if connected = true then begin
    try
    ser.SendString(command+chr(13)+chr(10));
    Form1.Memo1.Lines.Text := Form1.Memo1.Lines.Text+ser.RecvPacket(10)+' ';
    finally
    //ser.free;
  end;
  end;
end;

(**
 * connect the com port
 *)
procedure TForm1.connectButtonClick(Sender: TObject);
begin
  ser := TBlockSerial.Create;
  ser.RaiseExcept := false; // do not throw exceptions (maybe dirty hack, but the library used to raise exceptions any time :-) )
  try
    ser.Connect(comName.Text);
    ser.Config(strToInt(baudrate.Text), 8, 'N', 0, false, false);

    // enable/disable buttons when connected
    connected := true;
    connectButton.Enabled := false;
    disconnectButton.Enabled := true;
    sendButton.Enabled := true;
    left.Enabled := true;
    right.Enabled := true;
    forward.Enabled := true;
    backward.Enabled := true;
    stop.Enabled := true;
  finally
  end;
end;


procedure TForm1.FormCreate(Sender: TObject);
begin
  connected := false;
  stopped := true;
  Form1.Caption := Form1.Caption+' '+APP_VERSION;
end;

procedure TForm1.ForwardClick(Sender: TObject);
begin
sendCommand('FF');
end;

procedure TForm1.StopClick(Sender: TObject);
begin
sendCommand('SS');
stopped := true;
end;

procedure TForm1.disconnectButtonClick(Sender: TObject);
begin
  try
    // disable/enable buttons when disconnecting
    connected := false;
    connectButton.Enabled := true;
    disconnectButton.Enabled := false;
    sendButton.Enabled := false;
    left.Enabled := false;
    right.Enabled := false;
    forward.Enabled := false;
    backward.Enabled := false;
    stop.Enabled := false;

    // free COM connection
    ser.Free;
  finally
  end;
end;

procedure TForm1.LeftClick(Sender: TObject);
begin
  sendCommand('FB');
end;

procedure TForm1.RightClick(Sender: TObject);
begin
  sendCommand('BF');
end;

procedure TForm1.BackwardClick(Sender: TObject);
begin
  sendCommand('BB');
  stopped := false;
end;

procedure TForm1.Exit1Click(Sender: TObject);
begin
Application.Terminate;
end;

(**
 * key control
 *)
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
//memo1.Lines.text := memo1.lines.Text+FloatToStr(key)+' ';
case (key) of
  38: sendCommand('1'); // forward
  40: if (stopped) then sendCommand('BB') else sendCommand('SS'); // stop
  37: sendCommand('FB'); // left
  39: sendCommand('BF'); // right
end;
end;

(**
 * Sends command to COM port ('terminal') :-)
 *)
procedure TForm1.sendButtonClick(Sender: TObject);
begin
  sendCommand(command.Text);
end;

(**
 * shows 'About' forma
 *)
procedure TForm1.About1Click(Sender: TObject);
begin
    aboutForm.Show;
end;

end.

AlesH
Příspěvky: 323
Registrován: 25 úno 2013, 09:18

Re: Bluetooth-Arduino

Příspěvek od AlesH »

Ahoj. Myslím, že nemusíš měnit program v mobilu, ale stačí vhodně upravit program v Arduinu. Z mobilu zjevně chodí ASCII znaky, takže Arduino přijímá jejich hodnoty ("B' je dekadicky 66, 'F' je 70 a 'S' je 83) a ty pak vypisuje na LCD jako odpovídající řetězec znaků (podle očekávání a výsledků Tvého pozorování). Aby LCD displej vypisoval přímo jen ty přijaté znaky, tak je třeba místo lcd.print(val,DEC) použít funkci lcd.write() nebo lcd.print(val) [bez druhého parametru] ... to už jsme tu snad i někdy řešili (a taky Ti to vlastně včera napsal i "hubacekp"). Pro testování přijatých hodnot v Arduinu je možno použít jak dekadické hodnoty ("if (val==70) vpred();"), tak i znakové hodnoty ("if (val=='F') vpred();"). Ty znakové hodnoty musí být v apostrofech (ne ve dvojitých uvozovkách) a tu funkci vpred() jsem si vymyslel jen pro příklad. Při zpracování v Arduinu ale musíš počítat s tím, že z mobilu přichází několik znaků rychle po sobě. Nejprve dva znaky pro nastavení chodu motorů (pravého a levého) a pak i dva znaky označující "konec řádku" (dekadicky 10 a 13). Tohle zpracování více znaků po sobě si zkus vymyslet sám, ať se taky máš čím bavit :)
haas

Re: Bluetooth-Arduino

Příspěvek od haas »

Tak už to funguje, jen mám problém s tím načíst postupně do různých proměnných každý znak samostatně.Zkoušel jsem to pomocí funkce string , ale nějak to vůbec nešlo.
Nebyla by malá nápověda? :-) Jinak díky za rady.
AlesH
Příspěvky: 323
Registrován: 25 úno 2013, 09:18

Re: Bluetooth-Arduino

Příspěvek od AlesH »

OK, předpokládám, že jsi skutečně udělal pár neúspěšných pokusů o zpracování víceznakových řetězců. Posílám tedy příklad jednoho z mnoha možných řešení, kde stavím na předpokladu, že platné příkazové znaky jsou jen F nebo B nebo S (všechny ostatní znaky beru jako konce řetězce [začínám pak čekat na nový řetězec]). První platný znak řetězce považuju za příkaz pro pravý motor a druhý znak pro levý motor. Třetí a další platné znaky v řetězci ignoruju (v příkladu je nezpracovávám, ale nic nebrání tomu to doplnit). V příkladu místo motorů prostě jen ovládám svit interní LED na desce Arduino Duemilanove (na tom jsem kód zkoušel). Obecně postupuju tak, že přes Google si najdu pár obdobných řešení, vyberu si to, čemu rozumím, a pak to v co nejjednodušší formě vyzkouším na svém Arduinu. Doporučuju tento postup i ostatním.

Kód: Vybrat vše

char inByte;  // promenna pro prijaty znak
int pos = 0;  // ukazatel poradi znaku v retezci

void setup(){
  Serial.begin(9600);  // nastaveni rychlosti serioveho portu
  Serial.println("zadavejte dvojznakove retezce (zakoncene CR a LF)");
  // ocekavame dvojznakové retezce z kombinace znaku F nebo B nebo S a pak CR/LF
}

void loop(){
  if (Serial.available()) {
    inByte = Serial.read();
    if (inByte=='F' || inByte=='B' || inByte=='S') {
      if (pos==0) {
        // zpracovani prvniho prijateho platneho znaku na signal pro pravy motor
        if (inByte=='F') digitalWrite(13,HIGH);
      }
      if (pos==1) {
        // zpracovani druheho prijateho platneho znaku na signal pro levy motor
        if (inByte=='F') digitalWrite(13,LOW);
      }
      pos++; // posuneme ukazatel poradi znaku
    } else {
      pos = 0;  // ukazatel poradi nulujeme po neplatnem znaku
    }
    Serial.print(inByte); // echo prijatych znaku (pro kontrolu)
  }
}
haas

Re: Bluetooth-Arduino

Příspěvek od haas »

Moc díky za pomoc, funguje to perfektně :-)
Odpovědět