【发布时间】: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 通信,例如使用逻辑分析仪
-
你能提供一个你的组件是如何连接的连接图吗?