парсинг ascii to int

SiMuS
Offline
Зарегистрирован: 31.10.2011

Мужики помогите, никак не могу найти решение.

С serial порта прихрлит сообщение вида X10AD6080 фиксированной длины где X-признак начала сообщения, 10AD6080 -  число 279797888 в 16-ричной системе счисления.

Так вот никак не могу получить это число.

Надо  его в Long int записать.

 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012
SiMuS
Offline
Зарегистрирован: 31.10.2011

Спасибо, Вот так сделал, покритикуйте

 char ch = Serial1.read(); // Read a Byte
    if (ch == 'X')  //Find "X" flag
    {
      for (int i=0; i<8; i++) 
      {
        ch = Serial1.read();
        str += ch;
      }
      long idData = strtol( &str[0], NULL, 16);
}

 

faeton
faeton аватар
Offline
Зарегистрирован: 21.03.2016

SiMuS пишет:

Спасибо, Вот так сделал, покритикуйте

 char ch = Serial1.read(); // Read a Byte
    if (ch == 'X')  //Find "X" flag
    {
      for (int i=0; i<8; i++) 
      {
        ch = Serial1.read();
        str += ch;
      }
      long idData = strtol( &str[0], NULL, 16);
}

Как str объявлена? Проверка  коректности HEX числа не нужна? Проверка нарушения синхронизации (когда пакет фиксированной длинны вдруг не весь придёт и  флаг начала следующего прочитается как значение внутри битого пакета - не только битый, но следующий улетают. 

Но и самое главное, чтение порта, если потеряна связь (ничего не приходит), какой эффект даст - изучите.

SiMuS
Offline
Зарегистрирован: 31.10.2011
str - String
 
подскажите пожалуйста алгоритм решения замнченных вами проблем
 
 
 
По проверке порта весь данный цикл как раз обенут в 
 
if (Serial1.available() > 0) {
}

 

 
Этого достаточно или надо каждую операцию чтения с порта так же проверять?
SiMuS
Offline
Зарегистрирован: 31.10.2011

Такая функция подойдет для чтения из порта псоле флага?

byte ReadFromSerilal()

{
   while (Serial1.available() == 0) {

   }
   return (byte) Serial1.read();
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

SiMuS пишет:

Спасибо, Вот так сделал, покритикуйте

 char ch = Serial1.read(); // Read a Byte
    if (ch == 'X')  //Find "X" flag
    {
      for (int i=0; i<8; i++) 
      {
        ch = Serial1.read();
        str += ch;
      }
      long idData = strtol( &str[0], NULL, 16);
}

Если хотите помощи, а не потрындеть, приводите скетч полностью Как у Вас описана str? ХЗ! А на неё тут всё завязано.

Да, кстати, а сами-то запускали? Оно работает?

SiMuS
Offline
Зарегистрирован: 31.10.2011

Это проект снифера кан-шины автомобиля с помощью кан-шилда на базе mcp2515

Сектч построен на основе скетча gmlan https://github.com/Afterglow/arduino-gmlan

Мною переработаны функции для того чтобы девайс мог общаться с программой CanHacker которая принимает и отправляет пакеты через ком-порт следующими сообщениями:

TddddddddLDDDDDDDDDDDDDDDD

где T- начало пакета, dddddddd - ID заголовка , L - длина данных,  DD - байты данных

На данный момент основную задачу по приему и передаче данных в can шину он выполняет - то етсь работает.

Но поскольку решения той или иной задачи были подчерпнуты из кучи разных статей и гугла с минимальным опытом програмиирования - вполне допускаю много недосмотров и ошибок. 

Cкетч полностью тут тут https://github.com/Lastik-Lastikov/GMCanHacker

Основная страница ниже

#include <SPI.h>
#include <Wire.h>

#define P_SD      10
#define LED        8

//-------------------------
// MCP2515 Pin Defines
#define P_CS       10
#define P_SCK     13
#define P_MOSI   11
#define P_MISO   12
#define P_INT     3
#define rxPin     7
#define txPin     6

//-------------------------
//MCP2515
#define CNF3            0x28
#define CNF2            0x29
#define CNF1            0x2A
#define CANINTE  0x2B
#define CANINTF  0x2C
#define RXB0CTRL        0x60
#define RXB1CTRL        0x70
#define RXM0SIDH        0x20
#define RXM0SIDL        0x21
#define RXM0EID8        0x22
#define RXM0EID0        0x23
#define RXM1SIDH        0x24
#define RXM1SIDL        0x25
#define RXM1EID8        0x26
#define RXM1EID0        0x27
#define CANCTRL  0x0F
#define TXB0SIDH        0x31
#define TXB0SIDL        0x32
#define TXB0DLC  0x35
#define TXB0D0    0x36
#define TXB0CTRL        0x30

//-------------------------
//RX Filter Bytes...
#define RXF0SIDH        0x00
#define RXF1SIDH        0x04
#define RXF2SIDH        0x08
#define RXF3SIDH        0x10
#define RXF4SIDH        0x14
#define RXF5SIDH        0x18

//-------------------------
// MCP2515 defs
#define EXIDE     (1<<3)
#define EXMASK   0x1FFFFFFF
#define MCP_DLC_MASK            0x0F    /* 4 LSBits */
#define MCP_SIDH                0
#define MCP_SIDL                1
#define MCP_EID8                2
#define MCP_EID0                3

byte extID;
unsigned long heady;
byte datalength;
byte message[8];
int ConnStatus=0; //connection status

//long id;
byte byData[8]; // Allocate some space for the Bytes
char ch;
String str;
String inString = "";


void setup()
{

  Serial.begin(115200);
  Serial1.begin(115200);
  // set up pins for MCP2515
  pinMode(P_CS, OUTPUT);
  pinMode(P_SCK, OUTPUT);
  pinMode(P_MOSI, OUTPUT);
  pinMode(P_MISO, INPUT);

  SPI.setClockDivider(SPI_CLOCK_DIV2);
  SPI.setDataMode(SPI_MODE0);
  SPI.setBitOrder(MSBFIRST);
  SPI.begin();

  delay(1000);

  //  Serial1.println("Init MCP2515");
  mcp2515_init(33, 0x00);  //Iinitialize MCP2515: 1Mbit/s, 500, 125 Kbits/s, 33kps with filters enabled.
  mcp2515_write_register(CANCTRL, 0x00);
  delay(250);
}

void ReadSerial() {
  if (Serial1.available() > 0)
  {

    ch = Serial1.read(); // Read a Byte
    if (ch == 'T')  //Find "T" flag
    {
      for (int i=0; i<8; i++) 
      {
        ch = Serial1.read();;
        str += ch;
      }
      long idData = strtol( &str[0], NULL, 16);//convert ASCII HEX to INT
      int inChar = Serial1.read();   //read data length 
      if (isDigit(inChar)) {        //read data length
        inString += (char)inChar;
      }

      int length=inString.toInt(); // convert length  from char to int in bytes
      for (int i=0; i<length; i++) //add data bytes to array
      {
        byData[i]=SerialReadHexByte();
      }

      if (can_send_29bit_message(idData, sizeof(byData), byData)) //send to can
      {
        Serial.println("suceeded transmit");
      }
      else
      {
        Serial.println("failed");
      }
      //clear variables
      str="";
      inString = ""; 
      inChar=0;
      memset(byData, 0, sizeof(byData));
      idData =0;
    }
  }
}

void renderMsg(uint8_t address)
{
  mcp2515_read_can_id( address , &extID, &heady );
  mcp2515_read_canMsg( address, &datalength, &message[0]);
  processMessage();
}


void readCanAndSendToSerial() {

  byte flags;

  flags = mcp2515_read_register(CANINTF);
  if ((flags & 0x01) == 0x01)
  {
    renderMsg(0x61);
    // Clear the message flag..
    mcp2515_modifyRegister(CANINTF, 0x01, 0x00);
  }

  if ((flags & 0x02) == 0x02)
  {
    renderMsg(0x71);
    // Clear the message flag..
    mcp2515_modifyRegister(CANINTF, 0x02, 0x00);
  }
}


void processMessage() {


  Serial1.print("T");
  Serial1.print(heady, HEX);
  Serial1.print(datalength);
  for (int i = 0; i < datalength; i++)
  {
    Serial1.print(message[i], HEX);
  }
  Serial1.print("\r");



}

void do_connect() {

  if (Serial1.available() > 0) {
    ch = Serial1.read();
    delay(1000);
    if (ch =='V' || ch=='v') { //answer to version request

      Serial1.print("V1001\r");
      delay(1000);
    } 
    else if (ch =='O')  { //start main fuctions
      ConnStatus = 1;
      delay(1000);
    } 
  }
}
void loop()
{

  if (ConnStatus==1) {

    readCanAndSendToSerial();
    if (Serial1.available() > 0) {
      ReadSerial();
    }
  }
  else {
    do_connect();
  }



}