Forum: PC-Programmierung Serial1.write() - pointer


von Christian B. (christian_b606)


Lesenswert?

Hallo zusammen,

ich stehe gerade auf dem Schlauch und verstehe es nicht...


Ich möchte mit meinem Particle Electron ein GPS-Modul (SkyTraq Venus 6) 
ansteuern.



Folgendes konfiguriert den Venus 6 und liefert mir nen ACK und die 
richtige Message.
1
uint8_t queryA[] = {160, 161, 0, 2, 9, 2, 11, 13, 10};//binary mode
2
uint8_t queryB[] = {160, 161, 0, 2, 2, 1, 3, 13, 10}; //software query
3
4
void setup() {
5
  Serial.begin(9600);
6
  Serial1.begin(9600);
7
8
  delay(500);
9
  Serial1.write(queryA, sizeof(queryA));
10
  Serial1.flush();
11
}
12
13
void loop() {
14
15
  if (Serial1.available() > 0){
16
    char c = Serial1.read();
17
    Serial.print(c, HEX);
18
  } else {
19
    Serial.println("-------------");
20
    Serial1.write(queryB, sizeof(queryB));
21
    Serial1.flush();
22
    Serial.println("-------------");
23
    delay(50);
24
  }
25
26
};


Führe ich die commands jedoch über meine Klasse aus, erhalte ich vom 
receiver nur Müll. Der unterschied ist nur, dass ich in Serial1.write() 
einen uint8_t array pointer (msg_ptr) stecke.

1
#include "Particle.h"
2
#include "Serial2/Serial2.h"
3
#include "webservice.h"
4
#include "gps.h"
5
6
using gps::Gps;
7
8
SYSTEM_MODE(MANUAL);
9
SYSTEM_THREAD(ENABLED);
10
SerialLogHandler logHandler;
11
12
WebService projectWebService(20, 8080, "xxxxxx.xxx");
13
Gps projectGps(&Serial1);
14
15
16
void gpsCallback(uint8_t message, size_t logID) {
17
  String _message = (char*)message;
18
  projectWebService.put(&_message, logID);
19
};
20
21
void setup() {
22
  Serial.begin(9600);
23
  delay(500);
24
25
  projectGps.defaultMessageCallback(gpsCallback);
26
  projectGps.Connect(9600);
27
  projectGps.SetOutputFormatToBinary();
28
}
29
30
void loop() {
31
32
  projectGps.QuerySoftwareVersion();
33
  projectGps.ReadSerialPort();
34
   
35
}

gps.cpp (Die wichtigstens Teile vom Code)
1
#include "gps.h"
2
3
using namespace gps;
4
5
Gps::Gps(USARTSerial* serial) {
6
  _gpsSerial = serial;
7
  _is_connected = false;
8
  _reading_status = false;
9
};
10
11
bool Gps::Connect(uint8_t baudrate) {
12
  //Log.info("Connect");
13
  //_gpsSerial->begin(baudrate);
14
  Serial1.begin(baudrate);
15
  _is_connected = true;
16
  return true;
17
};
18
19
void Gps::defaultMessageCallback(void (*messageCallback)(uint8_t message, size_t logID))
20
{
21
  _messageCallback = messageCallback;
22
};
23
24
void Gps::StopReading() {
25
  Log.info("StopReading");
26
  _reading_status = false;
27
};
28
29
void Gps::ReadSerialPort() {
30
  Log.info("ReadSerialPort");
31
  _reading_status = true;
32
33
  uint8_t buffer[MAX_NOUT_SIZE];
34
  size_t len = 0;
35
  char incomingByte = 0;
36
37
  while (Serial1.available() && _reading_status) {
38
    //incomingByte = _gpsSerial->read();
39
    incomingByte = Serial1.read();
40
    buffer[len] = incomingByte;
41
    len++;
42
43
    if (len == MAX_NOUT_SIZE)
44
      break;
45
  }
46
47
  if (len > 0) {
48
    _BufferIncomingData(buffer, len);
49
  }
50
  else {
51
    Log.info("no data");
52
  };
53
54
  Serial.println("-----");
55
  return;
56
};
57
58
bool Gps::_SendMessage(uint8_t *msg_ptr, size_t length) {
59
  Log.info("_SendMessage");
60
61
  /*for (unsigned int i = 0; i < length; i++) {
62
    Serial.print(msg_ptr[i], HEX);
63
    Serial.print("-");
64
  };*/
65
66
  size_t bytes_written;
67
68
  //bytes_written=_gpsSerial->write(msg_ptr, length);
69
  bytes_written=Serial1.write(msg_ptr, length);
70
  //_gpsSerial->flush();
71
  Serial1.flush();
72
  //delay(50);
73
  // check that full message was sent to serial port
74
  if (bytes_written != length) {
75
      Log.error("Full message was not sent over serial port.");
76
      return false;
77
  }
78
  return true;
79
};
80
81
bool Gps::_ConfigureOutputFormat(OutputType output_type) {
82
  Log.info("_ConfigureOutputFormat");
83
  bool send_result;
84
85
  gps::ConfigureOutputFormat message;
86
  message.header.sync1 = SKYTRAQ_SYNC_BYTE_1;
87
  message.header.sync2 = SKYTRAQ_SYNC_BYTE_2;
88
  message.header.first_payload_byte = FIRST_PAYLOAD_BYTE;
89
  message.header.payload_length = CONFIGURE_OUTPUT_FORMAT_PAYLOAD_LENGTH;
90
  message.message_id = CFG_OUTPUT_FORMAT;
91
  message.type = output_type;
92
  message.footer.end1 = SKYTRAQ_END_BYTE_1;
93
  message.footer.end2 = SKYTRAQ_END_BYTE_2;
94
95
  //unsigned char* msg_ptr = (unsigned char*)&message;
96
  //_calculateCheckSum(msg_ptr+HEADER_LENGTH, CONFIGURE_OUTPUT_FORMAT_PAYLOAD_LENGTH,
97
  //                  &message.footer.checksum);
98
  uint8_t msg_ptr[] = {160, 161, 0, 2, 9, 2, 11, 13, 10};
99
  send_result = _SendMessage(msg_ptr,HEADER_LENGTH+CONFIGURE_OUTPUT_FORMAT_PAYLOAD_LENGTH+FOOTER_LENGTH);
100
  return send_result;
101
};
102
103
bool Gps::SetOutputFormatToBinary() {
104
  Log.info("SetOutputFormatToBinary");
105
106
  bool send_result;
107
  send_result = _ConfigureOutputFormat(BINARY_OUTPUT);
108
  return send_result;
109
};
110
111
bool Gps::QuerySoftwareVersion() {
112
    bool send_result;
113
114
  gps::QuerySoftwareVersion message;
115
  message.header.sync1 = SKYTRAQ_SYNC_BYTE_1;
116
  message.header.sync2 = SKYTRAQ_SYNC_BYTE_2;
117
  message.header.first_payload_byte = FIRST_PAYLOAD_BYTE;
118
  message.header.payload_length = QUERY_SOFTWARE_VERSION_PAYLOAD_LENGTH;
119
  message.message_id = QUERY_SOFTWARE_VERSION;
120
  message.software_type = SYSTEM_CODE;
121
  message.footer.end1 = SKYTRAQ_END_BYTE_1;
122
  message.footer.end2 = SKYTRAQ_END_BYTE_2;
123
124
  uint8_t msg_ptr[] = {160, 161, 0, 2, 2, 1, 3, 13, 10};
125
  //unsigned char* msg_ptr = (unsigned char*)&message;
126
  //_calculateCheckSum(msg_ptr+HEADER_LENGTH, QUERY_SOFTWARE_VERSION_PAYLOAD_LENGTH,
127
  //                  &message.footer.checksum);
128
129
  send_result = _SendMessage(msg_ptr,HEADER_LENGTH+QUERY_SOFTWARE_VERSION_PAYLOAD_LENGTH+FOOTER_LENGTH);
130
  return send_result;
131
};

Was mache ich falsch?

danke
chris

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Christian B. schrieb:
> uint8_t msg_ptr[] = {160, 161, 0, 2, 9, 2, 11, 13, 10};
>   send_result =
> _SendMessage(msg_ptr,HEADER_LENGTH+CONFIGURE_OUTPUT_FORMAT_PAYLOAD_LENGT 
H+FOOTER_LENGTH);


Deine "Längenberechnung" ist hier fragwürdig. Denn die von Dir weiter 
oben ausgefüllte "message"-Struktur verwendest Du überhaupt nicht, 
sondern das gleiche Array wie in Deinem Beispiel weiter oben, nämlich 
das unsinnigerweise "msg_ptr" genannte Array. Und wenn Du das der 
Sendefunktion übergibst, ist die Länge die Größe des Arrays und nicht 
irgendeine Addition irgendwelcher Konstanten.

Allerdings bist Du dann natürlich auch keinen Schritt weiter, denn das 
ganze Gehampel mit der "message"-Struktur ist dann komplett sinnlos.

von Christian B. (christian_b606)


Lesenswert?

Danke für deine Antwort.

Das "msg_ptr" genannte Array habe ich nur zum testen und zur 
Verdeutlichung zugefügt. Standard soll und wird die Message verwendet. 
Die übergebene Länge ist 9, wie die Länge des Arrays.
Auch wenn ich die 9 übergebe, funktioniert der Code nicht.


Danke
Christian

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Christian B. schrieb:
> Standard soll und wird die Message verwendet.

Das machst Du aber in Deinem Code nicht.

von Christian B. (christian_b606)


Lesenswert?

Unabhängig welches der beiden Arrays ich in die Methode _sendMessage und 
dann in Serial1.write stecke, es funktioniert nicht.
Die 9 Bytes werden zwar geschrieben,
 zumindest liefert mir write die gleiche Länge ==9 zurück, aber der GPS 
receiver reagiert nicht darauf.
Im ersten Beispiel jedoch schon! Nur, dass hier kein Pointer vorliegt.

Ebenso wenn ich die Message in ein uint_8 Array caste
uint_8* msg_ptr = (uint_8*)&message. ->keine Reaktion.
Auf unsigned char* msg_ptr = (unsigned char*)&message;  reagiert er 
ebenfalls nicht.

Und wie geschrieben, das array msg_ptr dient zur Veranschaulichung und 
ist identisch mit dem, welches in dem ersten Beispiel funktioniert. 
Daher habe ich es hierfür eingefügt. Daher kann man gleich Mal einen 
Fehler im struct Ausgrenzen.

Danke
Chris

von Bert3 (Gast)


Lesenswert?

Log doch mal die serielle Kommunikation bei dem laufenden Beispiel und 
deinem Code

oder z.B. mit Nullmodem-Kabel + 2xRS232(PCI oder FTDI) und Hercules 
(http://www.hw-group.com/products/hercules/index_de.html) die 
Kommunikation auf einen anderen Comport leiten

von Bert3 (Gast)


Lesenswert?


von Heiko G. (heikog)


Lesenswert?

Christian B. schrieb:

> projectGps.Connect(9600);

.
.
.

> bool Gps::Connect(uint8_t baudrate) {
>   //Log.info("Connect");
>   //_gpsSerial->begin(baudrate);
>   Serial1.begin(baudrate);
>   _is_connected = true;
>   return true;
> };

Für eine Baudrate von 9600 ist ein uint8_t ein bisschen zu klein :)

von Dirk B. (dirkb2)


Lesenswert?

Wie ist denn die Definition von gps::ConfigureOutputFormat ?

von Christian B. (christian_b606)


Lesenswert?

Omg. Dankeschön. Ich Honck.... 9600 passt doch nicht in uint_8...

Der Hinweis mit einem logger ist auch super. Dies werde ich machen. 
Somit komme ich zukünftig hoffentlich gleich auf das Problem. Denn 
Debuggen geht leider nicht  wirklich mit dem electron, soweit ich 
gelesen habe.

Melde mich wenn ich zuhause bin und es testen kann.


Danke
Chris

von Dirk B. (dirkb2)


Lesenswert?

Christian B. schrieb:
> Ich Honck.... 9600 passt doch nicht in uint_8...

Dagegen hat der Compiler Warnungen, die man evtl. aktiviern, aber in 
jedem Fall beachten muss.

von Christian B. (christian_b606)


Lesenswert?

Herzlichen Dank!!
Nun läuft der Code problemlos. :9
Es lag "nur" an dem falschen / zu kleinen Datentyp uint8_t

Danke für den Hinweis mit der compiler warnung, Dirk. Hier muss ich mich 
noch einlesen, da der Code aktuell noch in der particle cloud compiliert 
wird.
IDE verwende ich die Particle IDE (offline) mit PlatformIO.


vg
chris

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.