无法从树莓派pico(c sdk)发送串行数据

问题描述 投票:0回答:2

我正在制作一台远程控制机器,使用 pi pico 来驱动电机并读取一些传感器,并使用树莓派 4 来通过串行向 pi pico 发送命令并托管 Web 界面。

我目前正在测试 pi pico 串口的操作。为此,我通过以下方式将 pi pico 与树莓派连接起来:

目前,我正在使用以下文件:

1. main.c to receive and send
2. ring_queue.h where the code for the ring queue is located

main.c

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/uart.h"
#include "hardware/irq.h"
#include "ring_queue.h"

#define UART_ID uart0
#define BAUD_RATE 115200
#define DATA_BITS 8
#define STOP_BITS 1
#define PARITY    UART_PARITY_NONE
#define UART_TX_PIN 0
#define UART_RX_PIN 1
#define LED_PIN PICO_DEFAULT_LED_PIN


volatile int chars_rxed = 0;
volatile char uCommand[32];
volatile queue *rx_queue;
volatile queue *tx_queue;


void receive_rx(){
    while(uart_is_readable(UART_ID)){
      char ch = uart_getc(UART_ID);
      printf("Got a ch! %c\n", ch);
      if(ch != 10){
        uCommand[chars_rxed] = ch;
      }
      printf("Should have added it to uCommand: %s\n", uCommand);
      if(uCommand[chars_rxed] == '/'){
        printf("End of the command\n");
        queue_enqueue((queue*)rx_queue, (char*)uCommand);
        memset((char*)uCommand, 0, sizeof(uCommand));
        chars_rxed = 0;
        break;
      }
      if(ch != 10) chars_rxed++;
    }
}

void send_tx(){
  if(queue_empty((queue*)tx_queue) == 1){
   return;
 }
 else{
   printf("Trying to send something\n");
   char *foo = queue_dequeue((queue*)tx_queue);
   uart_write_blocking(UART_ID, (char*)foo, 32);
   //printf("%s\n", queue_dequeue((queue*)tx_queue));
 }
}

int main(){

  stdio_init_all();

  memset((char*)uCommand, 0, sizeof(uCommand));
  rx_queue = create_queue(32);
  tx_queue = create_queue(32);

  uart_init(UART_ID, BAUD_RATE);
  gpio_set_function(UART_TX_PIN, GPIO_FUNC_UART);
  gpio_set_function(UART_RX_PIN, GPIO_FUNC_UART);
  uart_set_hw_flow(UART_ID, false, false);
  uart_set_format(UART_ID, DATA_BITS, STOP_BITS, PARITY);
  uart_set_fifo_enabled(UART_ID, true);

  int UART_IRQ = UART_ID == uart0 ? UART0_IRQ : UART1_IRQ;

  irq_set_exclusive_handler(UART_IRQ, receive_rx);
  irq_set_enabled(UART_IRQ, true);
  uart_set_irq_enables(UART_ID, true, false);

    while (1){
        tight_loop_contents();
        if(queue_size((queue*)rx_queue) != 0){
          printf("Moving from rx to tx to print the received command\n");
          queue_enqueue((queue*)tx_queue, queue_dequeue((queue*)rx_queue));
        }
        send_tx();
      }
}

ring_queue.h

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


typedef struct {
    unsigned int tail;      // current tail
    unsigned int head;      // current head
    unsigned int size;      // current number of items
    unsigned int capacity;  // Capacity of queue
    char** data;                // Pointer to array of data
} queue;


queue *create_queue(unsigned int _capacity){
    printf("Malloc!\n");
    queue *myQueue = malloc(sizeof(queue));
    printf("Malloc done!\n");
    if (myQueue == NULL ){
        printf("Malloc failed!\n");
        return NULL;
    }
    else {
        printf("Malloc succeed!\n");
        myQueue->tail = -1;
        myQueue->head = 0;
        myQueue->size = 0;
        myQueue->capacity = _capacity;
        myQueue->data = malloc(_capacity * sizeof(char*));

        return myQueue;
    }
}


int queue_empty(queue *q) {
    if(q == NULL) return -1;
    else if(q->size == 0) return 1;
    else return 0;
}


int queue_full(queue *q) {
    if(q == NULL) return -1;
    else if(q->size == q->capacity) return 1;
    else return 0;
}


int queue_enqueue(queue *q, const char *item) {
    if (q == NULL) return -1;
    else if (queue_full(q) == 1) return 0;
    else {
      q->tail = (q->tail + 1) % q->capacity;
    q->data[q->tail] = strdup(item);
      q->size++;

      return 1;
    }
}

char *queue_dequeue(queue *q) {
    if(q == NULL) return NULL;
    else if(queue_empty(q) == 1) return '\0';
    else {
        char *item = q->data[q->head];
        q->head = (q->head + 1) % q->capacity;
        q->size--;

        return item;
    }
}


unsigned int queue_size(queue *q) {
    if (q == NULL) return - 1;
    else return q->size;
}


void free_queue(queue *q) {
  for(int i = 0; i < q->capacity; i++) free(q->data[i]);
  free(q->data);
    free(q);
}

我正在使用USB进行调试,当我发送一个简单的命令(通过arduino IDE)时,例如$MOVE /我可以正确接收它,但不会将其作为串行发送回来,而是使用USB,我可以(下面的printf) uart_write_blocking)。 当我尝试通过 uart 发送时,我在 arduino 串行提示符上收到随机字符,并且 pico 似乎也收到了它发送的一些字符。

c++ c embedded microcontroller raspberry-pi-pico
2个回答
1
投票

串口提示中的随机字符是什么?你期待什么角色?

uart_write_blocking的第三个参数(长度)

被硬编码为32,因此该函数将始终尝试将32个字节发送回树莓派——如果pico的字符串是,这可能会导致一些随机字符显示尝试发送实际上少于此。我会尝试将此代码片段更改为此,看看是否会停止随机字符。

printf("Trying to send something\n"); char *foo = queue_dequeue((queue*)tx_queue); uart_write_blocking(UART_ID, (char*)foo, strlen(foo)); // only send as many bytes as are in the string
    

0
投票
感谢您发布上述代码。它帮助我开始了。我在使用 USB 和 uart0 时遇到了类似的问题。无论波特率如何(9600 - 1500000),uart_write_blocking(uart0,...)总是发送垃圾

以下对我有用:

  1. 在CMakeLists.txt中启用USB和uart:

    pico_enable_stdio_uart(my-uart-prog 1) pico_enable_stdio_usb(我的uart-prog 1)

  2. 在调用 uart_init() 之前添加以下内容:

    // stdio_init_all(); // 否。默认 stdio 为 uart0。我想要USB stdio_usb_init(); // 首先在 USB 上启动 stdio。 stdio_uart_init(); //

    <== Adding this did the trick for me

有关更多详细信息,请参阅

RPi 运行时基础设施文档。

© www.soinside.com 2019 - 2024. All rights reserved.