Forum: Mikrocontroller und Digitale Elektronik STM32F4 USART float-Werte senden


von Han H. (ebuddy29)


Lesenswert?

Hallo,
ich hab ein kleines Problem bei dem ich nicht mehr weiter komme.
Ich habe einen Beschleunigungssensor der die gemessenen Werte über SPI 
an den STM32F4 weitergibt. Vom STM32 sollen nun die Daten über USART als 
float-Werte an einen Bluetooth-Adapeter "RN-42" weitergegeben werden.
Bisher konnte ich die Werte an den RN-42 als String über printf 
weitergeben. Dies soll aber nicht mehr als String/ASCII geschehen 
sondern direkt als floatwert. Habt ihr einen Tipp für mich? Achso, ich 
arbeite mit CooCox als Entwicklungsumgebung und die Ausgabe auf dem PC 
wird über HTerm dargestellt.

: Verschoben durch Moderator
von Dr. Sommer (Gast)


Lesenswert?

Warum möchtest du die sicherlich vom Accelerometer als Integer 
ausgegebenen Werte erst in einen Float konvertieren? Wegen der extra 
Ungenauigkeit? Wegen der benötigten Rechenzeit? Warum nicht den Integer 
direkt so wie er ist verschicken?

von Han H. (ebuddy29)


Lesenswert?

Danke für die schnelle Antwort.
Stimmt, das könnte ich auch machen. Aber auch hier die Frage: Wie?

von Dr. Sommer (Gast)


Lesenswert?

1
// Sendet einen Integer
2
template <typename T>
3
void transmitInteger (T val) {
4
  for (uint_fast8_t i = 0; i < sizeof (T); ++i) {
5
    // Warte auf Sende-Register leer
6
    while ((USART1->ISR & (1 << 7)) == 0);
7
    // Sende nächstes Datenbyte
8
    USART1->TDR = static_cast<uint8_t> (val & 0xFF);
9
    val = val >> 8;
10
  }
11
}
12
13
// Beispielcode
14
int main () {
15
  while (true) {
16
    uint32_t accVal = getValueFromAccelerometer ();
17
    transmitInteger (accVal);
18
  }
19
}
Diese Funktion sendet Integer beliebigen Typs im Little-Endian Format.

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Man könnte einen eigenen Datentyp mit union erstellen.

union Float_Byte
{
float fVal;
uint8_t bVal[sizeof(float)];
}

Damit kann man auf den Speicher mit Float zugreifen und die einzelnen 
Bytes.

: Bearbeitet durch User
von Han H. (ebuddy29)


Lesenswert?

Bisher habe ich es so gemacht:
- MPU6000.c://Daten des Sensors auslesen
SENSOR_Data MPU6000_Read(void)
{
  SENSOR_Data SENSOR_Dataset;
  uint8_t byte_H;
  uint8_t byte_L;


  // Read AccelX
  byte_H = MPU6000_SPI_read(MPUREG_ACCEL_XOUT_H);
  byte_L = MPU6000_SPI_read(MPUREG_ACCEL_XOUT_L);
  SENSOR_Dataset.a.x = (float)twos_complement(((byte_H << 8)| byte_L)) / 
4096;

- IO.c //hier werden die Daten in Strings geschrieben:
void send_data(SENSOR_Data SENSOR_Dataset, USER_Data data, 
SEND_Parameter par)
{
if (par.SEND_ACC)
  {
      // Accel
      printf("%.3f;", SENSOR_Dataset.a.x);
      printf("%.3f;", SENSOR_Dataset.a.y);
      printf("%.3f;", SENSOR_Dataset.a.z);
  }
}

- main.c
while (1)
   {
  if (Uart3_RxByte())
  cmd_checkCommand();

  if (IsMilliSecTimer(USART_TIMER_MS))
  {
  raw_data = read_data(fstate.apara.error, fstate.spara, fstate.cal);
  evaluate(&raw_data, &data, &fstate.apara);
  LED_off(LED4);
  Ruhelage(&data, &fstate.apara.error, &fstate.apara.mittelwert, 
init_MPU6000_Offset_for_a(fstate.cal));

  if (fstate.measurement_state == 1)
  {
  write_data_Flash(raw_data, data, &fstate);
  }
  else if (fstate.send_live){
#if SEND_VIA_USB
    send_data_USB(raw_data, data, fstate.spara);
#else
    send_data(raw_data, data, fstate.spara);
    LED_off(LED4);
#endif //SEND_VIA_USB
  }
  }
}

//ich dachte mir, dass ich dies einfach im io.c (statt den 
printf-Anweisungen)codieren könnte.

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.