【问题标题】:uart between atmega328p (C) and Feather m0 (Arduino) receiveatmega328p (C) 和 Feather m0 (Arduino) 之间的 uart 接收
【发布时间】:2021-06-04 10:34:41
【问题描述】:

我想通过 atmega328p 从我的 ac/gy 发送数据到一个羽毛 m0 模块。 atmega 使用 C 语言编写,使用以下 github 代码:https://github.com/YifanJiangPolyU/MPU6050

LoRa模块内接收数据的Arduino代码如下:

void do_send(osjob_t* j){
    // Check if there is not a current TX/RX job running
    if (LMIC.opmode & OP_TXRXPEND) {
        Serial.println(F("OP_TXRXPEND, not sending"));
    } else {
        // Prepare upstream data transmission at the next possible time.

byte strArray[30];
    int i = 0;
    if(Serial1.available()>0) {
       while (Serial1.available()>0){
          strArray[i] = Serial1.read();
          i++;
       }
            // send the 6 bytes payload to LoRaWAN port 7 --> now port 1
            LMIC_setTxData2(1, strArray, sizeof(strArray), 1); 

            digitalWrite(LED_BUILTIN, HIGH);    // turn the LED on by making the voltage HIGH                      //optional: for confirmation
    }

        }
    }
    // Next TX is scheduled after TX_COMPLETE event.
    //delay(60000);



void loop() {
    os_runloop_once();

}

但是,我似乎无法接收任何内容,并且显然无法使用 LMIC 函数向网关发送“字符数组”,因此尝试在字节数组中接收数据。非常感谢任何有关此的帮助或提示。我还将在下面包含 atmega328P 的 main.c 代码:

#define F_CPU 16000000UL
#define BAUD 9600

#include <inttypes.h>
#include <avr/sfr_defs.h>
#include <stdint.h>
#include <avr/io.h>
#include <util/delay.h>
#include <util/setbaud.h>
#include <avr/interrupt.h>
#include <math.h>
#include "mpu6050.h"
#include "mpu6050_reg.h"
#include "i2c.h"
#include "uart.h"

void timer_setup();
void get_time(double* dt);
volatile double count;
const double unit_t = 8/16000000;

int main(void){

sei();  
uart_init();
i2c_init();

DDRB |= _BV(5);

uint8_t ret;

int16_t accel_buff[3], gyro_buff[3];
double accelX, accelY, accelZ;
double gyroX, gyroY, gyroZ;
double biasX, biasY;
double phi_accel, theta_accel;
double phi_innov, theta_innov;
double phi_est, theta_est;
double phi_prev, theta_prev;

double dt;
char s[30];

// initialize & test MPU5060 availability
ret = i2c_start(MPU6050_ADDRESS+I2C_WRITE);
if(~ret){
    PORTB |= _BV(5);
    _delay_ms(200);
    PORTB &= ~(_BV(5));
}

mpu6050_init();
timer_setup();

// find gyro bias
biasX = 0;
biasY = 0;
uint8_t i;
for(i=0; i<20; i++){
    mpu6050_read_gyro_ALL(gyro_buff);
    biasX += gyro_buff[0];
    biasY += gyro_buff[1];
}
biasX = biasX/20*(3.14159/180)/1000/32768;
biasY = biasY/20*(3.14159/180)/1000/32768;

// initialization for Kalman filter
double P = 0.0;
double Q = 0.001;
double R = 0.03;
double Pp, K;
mpu6050_read_accel_ALL(accel_buff);
phi_prev = atan2(accelY, accelZ); // row
theta_prev = atan2(-accelX, sqrt(accelY*accelY+accelZ*accelZ)); // pitch

for(;;){
    get_time(&dt);
    mpu6050_read_accel_ALL(accel_buff);
    mpu6050_read_gyro_ALL(gyro_buff);
    
    // acceleration (m/s^2)
    accelX = accel_buff[0]*9.8*2/32768;
    accelY = accel_buff[1]*9.8*2/32768;
    accelZ = accel_buff[2]*9.8*2/32768;
    // gyro rate (rad/s)
    gyroX = gyro_buff[0]*(3.14159/180)/1000/32768;
    gyroY = gyro_buff[1]*(3.14159/180)/1000/32768;
    gyroZ = gyro_buff[2]*(3.14159/180)/1000/32768;

    // estimation
    phi_est = phi_prev + dt*(gyroX - biasX);
    theta_est = theta_prev + dt*(gyroY - biasY);
    Pp = P+Q;

    // innovation
    phi_accel = atan2(accelY, accelZ); // row
    phi_innov = phi_accel - phi_est;
    theta_accel = atan2(-accelX, sqrt(accelY*accelY+accelZ*accelZ)); // pitch
    theta_innov = theta_accel - theta_est;

    // Kalman gain
    K = Pp/(Pp+R);

    // correction
    phi_prev = phi_prev + K*phi_innov;
    theta_prev = theta_prev + K*theta_innov;
    P = (1-K)*Pp;
    
    uart_putchar('\n');
    _delay_ms(10);
    uart_putdouble(phi_prev); //phi, row
    uart_putdouble(theta_prev); //theta, pitch  
    uart_putdouble(dt);
    //_delay_ms(10);
        
}

}//end of main



void timer_setup(){
    TCCR1A = 0x00;
    TIMSK1 |= _BV(TOIE1);
    TCCR1B |= _BV(CS11);  
    TCCR1B &= ~( _BV(CS12)  | _BV(CS10)); // prescaler=8

}



void get_time(double * dt){
    cli();
        uint8_t l = TCNT1L;
        uint8_t h = TCNT1H;
        uint16_t step = h<<8 | l;
        *dt = (double)step*5e-7 + count*0.032768;
        count = 0;
    sei();
}


// timer 1 overflow interrupt handler
SIGNAL(TIMER1_OVF_vect){
    count += 1;
}

【问题讨论】:

  • 您没有进行任何故障排除?如果连接到 PC,ATmega 会打印一些东西吗?一个简单的 Serial1 到 Serial 草图会在串行监视器中打印一些东西吗?写一个只读取 Serial1 并收集数据的测试草图?
  • 就像@Juraj 说的,首先是检查UART 通信,例如使用逻辑分析仪
  • 你能提供一个你的组件是如何连接的连接图吗?

标签: c arduino uart


【解决方案1】:

将开发板连接到 PC 并检查 Arduino IDE 串行监视器是否可以获取或发送数据。

如果您的串行通信不起作用,您可以通过打开板上的 LED 来检查您是否超过了执行点。大多数开发板至少有 1 个,而使用 Arduino 只需将引脚设置为输出并在设置中设置 digitalWrite(LED_BUILTIN, 0),然后在您要检查的点设置 digitalWrite(LED_BUILTIN, 1)。

如果您的 atmega328p 在 arduino 板上(例如 uno、nano 等),您也应该以同样的方式检查它。串行验证和点过验证。

我愿意,然后依靠串口调试一段时间。

我很好奇,你认为条件“if(Serial1.available()>0)”是真的吗?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-06
    • 1970-01-01
    • 1970-01-01
    • 2021-10-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多