You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改Tmote Sky代码实现串口接收浮点数/整数及与Arduino UART通信

解决Tmote Sky通过UART接收整数/浮点数的问题

你的问题核心在于原来的代码只处理ASCII字符串,而你尝试发送的是二进制数值,或者错误地解析了字符串数据。下面分两种常用方案帮你实现需求:

方案一:ASCII文本解析(推荐,兼容现有代码)

这种方式是把数字转换成字符串(比如"10.48")发送,Tmote Sky收到字符串后再解析成数值,操作简单,不容易出错。

修改后的Tmote Sky代码

#include "contiki.h"
#include "dev/serial-line.h"
#include <stdlib.h>  // 引入字符串转数值的标准库函数

PROCESS(main_process, "main process");
AUTOSTART_PROCESSES(&main_process);

PROCESS_THREAD(main_process, ev, data) {
  PROCESS_BEGIN();

  for(;;) {
    PROCESS_WAIT_EVENT();
    if (ev == serial_line_event_message && data != NULL) {
      const char* input_str = (const char*)data;
      printf("Received string: '%s'\n", input_str);

      // 解析为整数
      int int_value = atoi(input_str);
      printf("Parsed integer: %d\n", int_value);

      // 解析为浮点数
      float float_value = atof(input_str);
      printf("Parsed float: %.2f\n", float_value);
    }
  }

  PROCESS_END();
}

关键说明

  1. 发送端操作:必须发送ASCII格式的数字字符串,比如用串口助手发送10.48(记得加换行/回车,因为serial_line模块默认以换行符作为字符串结束标记)。
  2. 之前的错误原因:你发送整数5却收到5408,大概率是发送端直接发送了二进制的int类型数据(4字节的0x00000005),而Tmote把这些非ASCII字节当成字符串解析,自然得到乱码结果。

方案二:二进制传输(高效传输场景)

如果需要更高效的传输(比如节省带宽、减少解析开销),可以直接发送浮点数的二进制字节,这时候需要跳过serial_line模块,直接操作UART底层。

Tmote Sky代码

#include "contiki.h"
#include "dev/uart0.h"
#include <string.h>

#define FLOAT_BYTE_COUNT 4  // AVR架构下float占4字节
uint8_t float_buffer[FLOAT_BYTE_COUNT];
uint8_t buffer_pos = 0;

// UART接收字节的回调函数
static void uart_receive_handler(unsigned char c) {
  if (buffer_pos < FLOAT_BYTE_COUNT) {
    float_buffer[buffer_pos++] = c;
    // 凑满4字节后重组为float
    if (buffer_pos == FLOAT_BYTE_COUNT) {
      float received_float;
      memcpy(&received_float, float_buffer, FLOAT_BYTE_COUNT);
      printf("Received binary float: %.2f\n", received_float);
      buffer_pos = 0;  // 重置缓冲区准备下一次接收
    }
  }
}

PROCESS(main_process, "main process");
AUTOSTART_PROCESSES(&main_process);

PROCESS_THREAD(main_process, ev, data) {
  PROCESS_BEGIN();

  // 初始化UART0,波特率115200,注册接收回调
  uart0_init(UART_BAUD_RATE(115200));
  uart0_set_input(uart_receive_handler);

  for(;;) {
    PROCESS_YIELD();
  }

  PROCESS_END();
}

发送端示例(Python)

需要把浮点数打包成二进制字节(注意Tmote Sky是小端字节序,要对应打包方式):

import serial
import struct

# 替换为你的串口端口号和波特率
ser = serial.Serial('COM3', 115200, timeout=1)
target_float = 10.48
# 按小端打包为4字节二进制
ser.write(struct.pack('<f', target_float))
ser.close()

关键注意点

  • 必须保证发送端和接收端的字节序一致(AVR是小端,所以用<f打包)。
  • 这种方式不会处理字符串终止符,所以要严格按固定字节数接收。

内容的提问来源于stack exchange,提问作者Haider Ali

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:14:55