#include <platform.h>
#include <sys_app.h>
#include <subghz_phy_app.h>
#include <radio.h>
#include <string.h>
/* USER CODE BEGIN Includes */
#include <stm32_timer.h>
#include <stm32_seq.h>
#include <utilities_def.h>
#include <app_version.h>
#include <subghz_phy_version.h>
/* USER CODE END Includes */
/* External variables ---------------------------------------------------------*/
/* USER CODE BEGIN EV */
/* USER CODE END EV */
/* Private typedef -----------------------------------------------------------*/
void MX_SPI2_Init(void);
void ADS1120reset(void);
uint16_t ADS1120readonce(void);
/* USER CODE BEGIN PTD */
#include <stdio.h>
#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SAMPLES_TO_COLLECT 10
static int16_t calibrated_samples[SAMPLES_TO_COLLECT][3];
static uint8_t sample_index = 0;
static uint8_t prediction_results[SAMPLES_TO_COLLECT] = {0};
typedef struct Vector
{
double x, y, z;
}Vector1;
const Vector1 a_static = { 9.8 / 1.414, 0, 9.8 / 1.414 };
//void cc(Vector1 a_static)
//{
// a_static.x=g/sqrt(2);
// a_static.y=0;
// a_static.z=g/sqrt(2);
//}
//Vector1 a_static;
// cc(*a_static);
void normalize(Vector1 *v) // ¸ÄΪָÕë´«µÝ
{
double l = sqrt(v->x*v->x + v->y*v->y + v->z*v->z);
v->x /= l;
v->y /= l;
v->z /= l;
}
Vector1 cross(Vector1 a, Vector1 b)
{
Vector1 result;
result.x = a.y * b.z - a.z * b.y;
result.y = a.z * b.x - a.x * b.z;
result.z = a.x * b.y - a.y * b.x;
return result;
}
Vector1 Convert(double R[3][3], Vector1 a_device)
{
Vector1 a_world;
a_world.x = R[0][0] * a_device.x + R[1][0] * a_device.y + R[2][0] * a_device.z;
a_world.y = R[0][1] * a_device.x + R[1][1] * a_device.y + R[2][1] * a_device.z;
a_world.z = R[0][2] * a_device.x + R[1][2] * a_device.y + R[2][2] * a_device.z;
return a_world;
}
Vector1 Remove(Vector1 a_world, double g)
{
Vector1 a_motion;
a_motion.x = a_world.x/100;
a_motion.y = a_world.y/100;
a_motion.z = (a_world.z - g)/100;
return a_motion;
}
Vector1 processBufferTx(uint8_t *BufferTx)
{
Vector1 res = { 0, 0, 0 };
for (int rain = 0; rain < 10; rain++)
{
int ax_sign = BufferTx[5 + 6 * rain] ? -1 : 1;
int ax_value = BufferTx[6 + 6 * rain];
double ax = ax_sign * (ax_value * 100.0);
int ay_sign = BufferTx[7 + 6 * rain] ? -1 : 1;
int ay_value = BufferTx[8 + 6 * rain];
double ay = ay_sign * (ay_value * 100.0);
int az_sign = BufferTx[9 + 6 * rain] ? -1 : 1;
int az_value = BufferTx[10 + 6 * rain];
double az = az_sign * (az_value * 100.0);
ax = ax / 4.0 * 0.976;
ay = ay / 4.0 * 0.976;
az = az / 4.0 * 0.976;
res.x += ax;
res.y += ay;
res.z += az;
}
res.x /= 10;
res.y /= 10;
res.z /= 10;
return res;
}
Vector1 solve(Vector1 raw_data)
{
static Vector1 a_static = {9.8/1.414, 0, 9.8/1.414};
normalize(&a_static);
/* ×ø±êϵת»» */
Vector1 t = { 1, 0, 0 };
Vector1 x_temp = cross(t, a_static);
normalize(&x_temp);
Vector1 y = cross(a_static, x_temp);
normalize(&y);
double R[3][3] = {
{x_temp.x, y.x, a_static.x},
{x_temp.y, y.y, a_static.y},
{x_temp.z, y.z, a_static.z}
};
/* ×ø±êת»» */
Vector1 a_world = Convert(R, raw_data);
/* È¥³ýÖØÁ¦Ó°Ïì */
return Remove(a_world, 9.8);
}
#define MAX_DATA_POINTS 200 // ѵÁ·¼¯´óС
#define INPUT_FEATURE_DIM 3 // Ñù±¾Î¬¶È
/* ½á¹¹Ìå */
/* ѵÁ·Êý¾Ý½á¹¹Ìå */
typedef struct {
int16_t f[3]; // ÌØÕ÷Êý×é
uint8_t label; // ±êÇ©
} DataPoint;
/* È«¾ÖѵÁ·Êý¾Ý¼¯£¨ÒÑÔ¤ÖÃ50¸öÑù±¾£© */
DataPoint dataset[MAX_DATA_POINTS] = {
{{35, -13, -9}, 1},{{37, -13, -11}, 1},{{35, -9, -19}, 1},{{36, -8, -18}, 1},
{{37, -5, -18}, 1},{{37, -11, -23}, 1},{{36, -7, -17}, 1},{{36, -6, -15}, 1},
{{36, -9, -12}, 1},{{35, -9, -12}, 1},{{35, -8, -11}, 1},
{{34, -8, -11}, 1},{{35, -16, -6}, 1},{{35, -16, -5}, 1},
{{36, -17, -6}, 1},{{35, -17, -6}, 1},{{35, -18, -7}, 1},
{{36, -18, -6}, 1},{{36, -18, -6}, 1},{{36, -18, -6}, 1},
{{36, -17, -4}, 1},{{37, -16, -3}, 1},{{37, -23, -6}, 1},
{{37, -23, -6}, 1},{{37, -18, 0}, 1},{{37, -18, -1}, 1},
{{38, -18, -1}, 1},{{38, -18, -1}, 1},{{38, -8, -11}, 1},
{{38, -9, -12}, 1},{{38, -9, -12}, 1},{{26, -8, -11}, 1},
{{25, -20, 0}, 1},{{25, -20, 0}, 1},{{29, -19, 1}, 1},
{{28, -20, 0}, 1},{{30, -19, 1}, 1},{{29, -19, -1}, 1},
{{19, -23, -4}, 0},{{18, -23, -5}, 0},{{15, -14, -6}, 0},
{{20, -23, -11}, 0},{{19, -27, -17}, 0},{{20, -20, -10}, 0},
{{26, -15, -2}, 0},{{27, -16, -3}, 0},{{27, -15, -2}, 0},
{{28, -16, -3}, 0},{{27, -15, -3}, 0},{{27, -16, -3}, 0},
{{26, -8, -11}, 0},{{25, -8, -11}, 0},{{27, -8, -11}, 0},
{{27, -8, -11}, 0},{{3, -14, -1}, 0},{{4, -14, 0}, 0},
{{25, -8, -11}, 0},{{27, -8, -11}, 0},{{27, -26, 8}, 0},
{{3, -24, 9}, 0},{{4, -24, 10}, 0},{{3, -24, 10}, 0},
{{4, -24, 10}, 0},{{3, -23, 10}, 0},{{4, -23, 10}, 0},
{{7, -23, 10}, 0},{{4, -23, 9}, 0},{{4, -23, 9}, 0},
{{4, -23, 11}, 0},{{0, -25, 10}, 0},{{0, -25, 9}, 0},
{{0, -27, 9}, 1},{{28, -26, 12}, 2},{{30, -27, 10}, 2},
{{30, -27, 10}, 2},{{29, -27, 10}, 2},{{29, -28, 9}, 2},
{{29, -28, 9}, 2},{{28, -28, 9}, 2},{{28, -28, 7}, 2},
{{26, -29, 8}, 2},{{27, -28, 7}, 2},{{26, -40, -4}, 2},
{{23, -40, -4}, 2},{{26, -38, -4}, 2},{{24, -39, -5}, 2},
{{25, -37, -3}, 2},{{-1, -40, -4}, 2},{{17, -29, 6}, 2},
{{20, -29, 8}, 2},{{20, -28, 8}, 2},{{17, -28, 7}, 2},
{{18, -29, 6}, 2},{{19, -30, 6}, 2},{{22, -29, 6}, 2},
{{20, -28, 6}, 2},{{21, -28, 4}, 2},{{23, -27, 6}, 2},
{{19, -27, 6}, 2},{{20, -28, 5}, 2},{{18, -28, 5}, 2},
{{22, -30, 2}, 2},{{23, -34, -1}, 2},{{11, -27, 6}, 2},
{{16, -29, 5}, 2},{{16, -33, 1}, 2},{{28, -28, 7}, 2},
{{28, -28, 6}, 2},{{27, -28, 7}, 2},{{28, -28, 7}, 2},{{26, -29, 6}, 2},
{{25, -28, 6}, 2},{{27, -29, 6}, 2},{{28, -30, 6}, 2},
{{29, -28, 6}, 2},{{31, -28, 6}, 2},{{26, -37, -3}, 2},
{{22, -38, -4}, 2},{{22, -35, -1}, 2},{{21, -40, -6}, 2},
{{27, -25, 8}, 2},{{28, -24, 9}, 2},{{27, -25, 7}, 2},
{{30, -25, 7}, 2},{{31, -25, 7}, 2},{{30, -27, 9}, 2},
{{30, -28, 8}, 2},{{30, -29, 6}, 2},{{29, -27, 9}, 2},
{{30, -25, 11}, 2},{{30, -23, 11}, 2},{{28, -25, 11}, 2},
{{26, -25, 9}, 2},{{20, -37, -1}, 2},{{16, -39, -2}, 2},
{{9, -38, -3}, 2},{{13, -38, -3}, 2},{{12, -37, -2}, 2},
{{-10, -37, -2}, 2},{{0, -30, 4}, 2},{{10, -27, 9}, 2},
{{9, -26, 8}, 2},{{9, -27, 9}, 2},{{12, -27, 9}, 2},
{{14, -26, 8}, 2},{{16, -26, 9}, 2},{{13, -25, 10}, 2},{{15, -25, 11}, 2},
{{16, -25, 11}, 2},{{17, -25, 11}, 2},{{16, -25, 11}, 2},
{{13, -26, 9}, 2},{{15, -27, 9}, 2},{{22, -29, 6}, 2},
{{23, -29, 6}, 2},{{24, -28, 6}, 2},{{24, -26, 5}, 2},
{{25, -26, 6}, 2},{{25, -25, 7}, 2},{{24, -26, 8}, 2},
{{25, -26, 6}, 2},{{25, -25, 7}, 2},{{23, -26, 8}, 2},
{{3, -28, 5}, 2},{{3, -28, 6}, 2},{{1, -29, 6}, 2},
{{2, -30, 6}, 2},{{3, -30, 4}, 2},{{25, -21, 4}, 2},
{{25, -21, 4}, 2},{{25, -21, 4}, 2},{{26, -21, 5}, 2},
{{25, -21, 6}, 2},{{26, -21, 4}, 2},{{32, -11, 14}, 2},
{{32, -11, 14}, 2},{{32, -11, 15}, 2},{{32, -10, 16}, 2},
{{20, 3, 27}, 2},{{19, 5, 29}, 2},{{13, 7, 31}, 2},
{{-5, -6, 16}, 2},{{-6, -13, 9}, 2},{{4, -4, 21}, 2},
{{11, -23, 1}, 2},{{9, -23, 1}, 2},{{9, -23, 0}, 2},
{{10, -23, 1}, 2},{{11, -23, 0}, 2},
{{7, -23, 0}, 2},{{8, -24, -1}, 2},{{10, -24, -1}, 2},
{{10, -23, -1}, 2},{{11, -23, 0}, 2},{{37, -17, 6}, 2},
{{36, -18, 5}, 2},{{34, -17, 6}, 2},{{35, -18, 5}, 2},
{{35, -17, 7}, 2},{{34, -17, 7}, 2},{{35, -18, 6}, 2},
{{36, -17, 6}, 2},{{34, -17, 6}, 2},{{35, -16, 6}, 2},
{{34, 7, -23}, 3},{{33, 1, -23}, 3},{{30, -5, -29}, 3},
{{22, -9, -32}, 3},{{16, -6, -30}, 3},{{22, -10, -34}, 3},{{12, 0, -23}, 3},
{{14, -7, -28}, 3},{{11, -3, -24}, 3},{{13, 2, -16}, 3},
{{27, -20, 6}, 3},{{28, -21, 6}, 3},{{27, -21, 5}, 3},
{{27, -21, 5}, 3},{{27, -19, 4}, 3},{{26, -21, 4}, 3},
{{26, -22, 4}, 3},{{25, -25, 5}, 3},{{25, -26, 4}, 3},
{{22, -33, -2}, 3},{{9, -38, 2}, 3},{{12, -34, 6}, 3},{{18, -23, 2}, 3},
{{17, -22, 1}, 3},{{19, -20, 0}, 3},{{20, -21, 0}, 3},
{{21, -21, 2}, 3},{{20, -21, 2}, 3},{{20, -21, 2}, 3},
{{20, -21, 1}, 3},{{22, -20, 2}, 3},{{23, -23, 3}, 3},
{{23, -10, -15}, 3},{{23, -16, -23}, 3},{{19, -17, -24}, 3},
{{9, -14, -21}, 3},{{18, -21, -27}, 3},{{15, -14, -20}, 3},{{18, -20, -23}, 3},
{{-1, -5, -8}, 3},{{9, -5, -8}, 3},{{8, -4, -7}, 3}
};
float train_mean[3] = {0};
float train_std[3] = {0};
void compute_train_stats(void);
float euclidean_distance(const float *a, const float *b);
uint8_t predict_class(const int16_t *features);
void test_knn_performance(void);
float euclidean_distance(const float *a, const float *b) {
return sqrt(pow(a[0]-b[0],2) + pow(a[1]-b[1],2) + pow(a[2]-b[2],2));
}
void compute_train_stats() {
// ¼ÆËã¾ùÖµ
float sum[3] = {0};
for (int i = 0; i < MAX_DATA_POINTS; i++) {
sum[0] += dataset[i].f[0];
sum[1] += dataset[i].f[1];
sum[2] += dataset[i].f[2];
}
train_mean[0] = sum[0] / MAX_DATA_POINTS;
train_mean[1] = sum[1] / MAX_DATA_POINTS;
train_mean[2] = sum[2] / MAX_DATA_POINTS;
// ¼ÆËã±ê×¼²î
float variance[3] = {0};
for (int i = 0; i < MAX_DATA_POINTS; i++) {
variance[0] += pow(dataset[i].f[0] - train_mean[0], 2);
variance[1] += pow(dataset[i].f[1] - train_mean[1], 2);
variance[2] += pow(dataset[i].f[2] - train_mean[2], 2);
}
for (int j = 0; j < 3; j++) {
train_std[j] = sqrt(variance[j]/MAX_DATA_POINTS);
if (train_std[j] < 1e-5) train_std[j] = 1e-5; // ·ÀÖ¹³ýÁã
}
}
/* KNNÔ¤²âʵÏÖ£¨k=10£© */
uint8_t predict_class(const int16_t *features) {
float normalized_input[3];
// ÊäÈëÌØÕ÷¹éÒ»»¯
for (int j=0; j<3; j++) {
normalized_input[j] = (features[j]-train_mean[j])/train_std[j];
}
// ´æ´¢¾àÀëºÍ±êÇ©
float distances[MAX_DATA_POINTS];
uint8_t labels[MAX_DATA_POINTS];
const uint8_t k = 7; // ¾ÊµÑéµ÷ÕûµÄ×î¼ÑkÖµ
// ¼ÆËãËùÓоàÀë
for (int i=0; i<MAX_DATA_POINTS; i++) {
float normalized_train[3];
for (int j=0; j<3; j++) {
normalized_train[j] = (dataset[i].f[j]-train_mean[j])/train_std[j];
}
distances[i] = euclidean_distance(normalized_input, normalized_train);
labels[i] = dataset[i].label;
}
// ÕÒ³ök¸ö×î½üÁÚ
for (int i=0; i<k; i++) {
int min_idx = i;
for (int j=i+1; j<MAX_DATA_POINTS; j++) {
if (distances[j] < distances[min_idx]) min_idx = j;
}
// ½»»»Î»ÖÃ
float tmp_d = distances[i];
distances[i] = distances[min_idx];
distances[min_idx] = tmp_d;
uint8_t tmp_l = labels[i];
labels[i] = labels[min_idx];
labels[min_idx] = tmp_l;
}
// ¼ÓȨͶƱ£¨Ê¹ÓþàÀëµ¹Êý×÷ÎªÈ¨ÖØ£©
float weight_sum[4] = {0};
for (int i=0; i<k; i++) {
weight_sum[labels[i]] += 1/(distances[i]+1e-5); // ·ÀÖ¹³ýÁã
}
// È·¶¨×îÖÕÀà±ð
uint8_t predicted = 0;
float max_weight = 0;
for (int i=0; i<4; i++) {
if (weight_sum[i] > max_weight) {
max_weight = weight_sum[i];
predicted = i;
}
}
printf("predicted label: %d\n", predicted);
return predicted;
}
/* USER CODE END EV */
int * features;
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
typedef enum
{
S_IDLE,
S_RX,
S_RX_TIMEOUT,
S_RX_ERROR,
S_TX,
S_TXing,
S_TX_TIMEOUT,
S_SEND_DATA,
} States_t;
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* Configurations */
/*Timeout*/
#define RX_TIMEOUT_VALUE 5000
#define TX_TIMEOUT_VALUE 10000
//????
#define SEND_PERIOD_MS 15000
//??ID
#define LOCAL_ID 0x01
//??ID
#define REMOTE_ID 0x10
//????
#define DATA_TYPE 0x01
/*Size of the payload to be sent*/
/* Size must be greater of equal the PING and PONG*/
#define MAX_APP_BUFFER_SIZE 255
#if (PAYLOAD_LEN > MAX_APP_BUFFER_SIZE)
#error PAYLOAD_LEN must be less or equal than MAX_APP_BUFFER_SIZE
#endif /* (PAYLOAD_LEN > MAX_APP_BUFFER_SIZE) */
/*????*/
/*SHT3x??*/
#define SHT3x_ADDRESS 0x44<<1 //?????7?,??????
#define SCL_Pin GPIO_PIN_15
#define SCL_GPIO_Port GPIOB
#define SDA_Pin GPIO_PIN_9
#define SDA_GPIO_Port GPIOB
#define SHT3x_W_SCL(x) HAL_GPIO_WritePin(GPIOB, SCL_Pin, (GPIO_PinState)(x))
#define SHT3x_W_SDA(x) HAL_GPIO_WritePin(GPIOB, SDA_Pin, (GPIO_PinState)(x))
#define SHT3x_R_SDA() HAL_GPIO_ReadPin(GPIOB, SDA_Pin)
#define SHT3x_R_SCL() HAL_GPIO_ReadPin(GPIOB, SCL_Pin)
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/*??????*/
void SHT3x_I2C_START(){
SHT3x_W_SDA(1);
SHT3x_W_SCL(1);
HAL_Delay(1);
SHT3x_W_SDA(0);
HAL_Delay(1);
SHT3x_W_SCL(0);
HAL_Delay(1);
}
/*??????*/
void SHT3x_I2C_STOP(){
SHT3x_W_SDA(0);
SHT3x_W_SCL(1);
HAL_Delay(1);
SHT3x_W_SDA(1);
HAL_Delay(1);
}
/**
* @brief ??????
* @param ?
* @retval 1-?????,0-????
*/
uint8_t WaitAck(void)
{
uint8_t ret;
SHT3x_W_SCL(1);
HAL_Delay(1);
if(SHT3x_R_SDA()){
ret=1;
}
else{
ret=0;
}
SHT3x_W_SCL(0);
HAL_Delay(1);
return ret;
}
/**
* @brief I2C??????
* @param Byte ????????
* @retval ?
*/
void SHT3x_I2C_SendByte(uint8_t Byte)
{
uint8_t i;
for (i = 0; i < 8; i++)
{
SHT3x_W_SDA((Byte<<i) & 0x80 );
SHT3x_W_SCL(1);
HAL_Delay(1);
SHT3x_W_SCL(0);
HAL_Delay(1);
}
SHT3x_W_SDA(1);//??SDA??
}
/**
* @brief ????????
* @param MSB ?8?
* @param LSB ?8?
* @retval ?
*/
void SHT3x_WriteByte(uint8_t MSB,uint8_t LSB)
{
SHT3x_I2C_START(); //??????
SHT3x_I2C_SendByte(SHT3x_ADDRESS); //???????
WaitAck();
SHT3x_I2C_SendByte(MSB);//???8???
WaitAck();
SHT3x_I2C_SendByte(LSB);//???8???
WaitAck();
SHT3x_I2C_STOP();
}
/**
* @brief I2C??????
* @param NACK 1-?????,0-????
* @retval ????????
*/
uint8_t SHT3x_ReadData(uint8_t NACK)
{
uint8_t i,Byte=0;
SHT3x_W_SDA(1);//??SDA??
for (i = 0; i < 8; i++)
{
SHT3x_W_SCL(1);
HAL_Delay(1);
Byte=Byte|(SHT3x_R_SDA()<<(7-i));
HAL_Delay(1);
SHT3x_W_SCL(0);
HAL_Delay(1);
}
SHT3x_W_SDA(NACK);//????/?????
SHT3x_W_SCL(1);
HAL_Delay(1);
SHT3x_W_SCL(0);
HAL_Delay(1);
SHT3x_W_SDA(1);//??SDA??
return Byte;
}
/*????SHT3x*/
void SHT3x_SoftReset(void)
{
SHT3x_WriteByte(0x30,0xA2); //?????SHT3x
}
/*?????*/
void SHT3x_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOB, SCL_Pin | SDA_Pin, GPIO_PIN_SET);
/*Configure GPIO pins : PBPin PBPin */
GPIO_InitStruct.Pin = SCL_Pin | SDA_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
SHT3x_W_SCL(1);
SHT3x_W_SDA(1);
// SHT3x_WriteByte(0X27,0X21); //????????(??10?,Medium Repeatability)
HAL_Delay(1);
}
#define SCL1_Pin GPIO_PIN_4
#define SCL1_GPIO_Port GPIOA
#define SDA1_Pin GPIO_PIN_15
#define SDA1_GPIO_Port GPIOA
#define SHT3x1_W_SCL(x) HAL_GPIO_WritePin(GPIOA, SCL1_Pin, (GPIO_PinState)(x))
#define SHT3x1_W_SDA(x) HAL_GPIO_WritePin(GPIOA, SDA1_Pin, (GPIO_PinState)(x))
#define SHT3x1_R_SDA() HAL_GPIO_ReadPin(GPIOA, SDA1_Pin)
#define SHT3x1_R_SCL() HAL_GPIO_ReadPin(GPIOA, SCL1_Pin)
/* USER CODE END EF */
void MyI2C_W_SCL(uint8_t BitValue)
{
SHT3x1_W_SCL(BitValue);
HAL_Delay(1);
}
void MyI2C_W_SDA(uint8_t BitValue)
{
SHT3x1_W_SDA(BitValue);
HAL_Delay(1);
}
uint8_t MyI2C_R_SDA(void)
{
uint8_t BitValue;
BitValue = SHT3x1_R_SDA();
HAL_Delay(1);
return BitValue;
}
void MyI2C_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, SCL1_Pin | SDA1_Pin, GPIO_PIN_SET);
/*Configure GPIO pins : PBPin PBPin */
GPIO_InitStruct.Pin = SCL1_Pin | SDA1_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
// GPIO_InitStruct.Pin = GPIO_PIN_5;
// GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
// GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
void MyI2C_Start(void)
{
MyI2C_W_SDA(1);
MyI2C_W_SCL(1);
MyI2C_W_SDA(0);
MyI2C_W_SCL(0);
}
void MyI2C_Stop(void)
{
MyI2C_W_SDA(0);
MyI2C_W_SCL(1);
MyI2C_W_SDA(1);
}
void MyI2C_SendByte(uint8_t Byte)
{
uint8_t i;
for (i = 0; i < 8; i ++)
{
MyI2C_W_SDA(Byte & (0x80 >> i));
MyI2C_W_SCL(1);
MyI2C_W_SCL(0);
}
}
uint8_t MyI2C_ReceiveByte(void)
{
uint8_t i, Byte = 0x00;
MyI2C_W_SDA(1);
for (i = 0; i < 8; i ++)
{
MyI2C_W_SCL(1);
if (MyI2C_R_SDA() == 1){Byte |= (0x80 >> i);}
MyI2C_W_SCL(0);
}
return Byte;
}
void MyI2C_SendAck(uint8_t AckBit)
{
MyI2C_W_SDA(AckBit);
MyI2C_W_SCL(1);
MyI2C_W_SCL(0);
}
uint8_t MyI2C_ReceiveAck(void)
{
uint8_t AckBit;
MyI2C_W_SDA(1);
MyI2C_W_SCL(1);
AckBit = MyI2C_R_SDA();
MyI2C_W_SCL(0);
return AckBit;
}
#define MPU6050_ADDRESS 0x32
void MPU6050_WriteReg(uint8_t RegAddress, uint8_t Data)
{
MyI2C_Start();
MyI2C_SendByte(MPU6050_ADDRESS);
MyI2C_ReceiveAck();
MyI2C_SendByte(RegAddress);
MyI2C_ReceiveAck();
MyI2C_SendByte(Data);
MyI2C_ReceiveAck();
MyI2C_Stop();
}
uint8_t MPU6050_ReadReg(uint8_t RegAddress)
{
uint8_t Data;
MyI2C_Start();
MyI2C_SendByte(MPU6050_ADDRESS);
MyI2C_ReceiveAck();
MyI2C_SendByte(RegAddress);
MyI2C_ReceiveAck();
MyI2C_Start();
MyI2C_SendByte(MPU6050_ADDRESS | 0x01);
MyI2C_ReceiveAck();
Data = MyI2C_ReceiveByte();
MyI2C_SendAck(1);
MyI2C_Stop();
return Data;
}
#define MPU6050_PWR_MGMT_1 0x20
#define MPU6050_PWR_MGMT_2 0x25
#define MPU6050_SMPLRT_DIV 0x23
void MPU6050_Init(void)
{
MyI2C_Init();
MPU6050_WriteReg(MPU6050_PWR_MGMT_1, 0x60);
MPU6050_WriteReg(MPU6050_PWR_MGMT_2, 0x84);
MPU6050_WriteReg(MPU6050_SMPLRT_DIV, 0x00);
}
#define MPU6050_ACCEL_XOUT_H 0x29
#define MPU6050_ACCEL_XOUT_L 0x28
#define MPU6050_ACCEL_YOUT_H 0x2B
#define MPU6050_ACCEL_YOUT_L 0x2A
#define MPU6050_ACCEL_ZOUT_H 0x2D
#define MPU6050_ACCEL_ZOUT_L 0x2C
void MPU6050_GetData(int16_t *AccX, int16_t *AccY, int16_t *AccZ)
{
uint8_t DataH, DataL;
DataH = MPU6050_ReadReg(MPU6050_ACCEL_XOUT_H);
DataL = MPU6050_ReadReg(MPU6050_ACCEL_XOUT_L);
*AccX = (DataH << 8) | DataL;
DataH = MPU6050_ReadReg(MPU6050_ACCEL_YOUT_H);
DataL = MPU6050_ReadReg(MPU6050_ACCEL_YOUT_L);
*AccY = (DataH << 8) | DataL;
DataH = MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_H);
DataL = MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_L);
*AccZ = (DataH << 8) | DataL;
}
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* Radio events function pointer */
static RadioEvents_t RadioEvents;
/* USER CODE BEGIN PV */
/*Ping Pong FSM states */
static States_t State = S_IDLE;
/* App Rx Buffer*/
static uint8_t BufferRx[MAX_APP_BUFFER_SIZE];
/* App Tx Buffer*/
static uint8_t BufferTx[MAX_APP_BUFFER_SIZE];
/* Last Received Buffer Size*/
uint16_t RxBufferSize = 0;
/* Last Received packer Rssi*/
int8_t RssiValue = 0;
/* Last Received packer SNR (in Lora modulation)*/
int8_t SnrValue = 0;
/* Led Timers objects*/
//?????
static UTIL_TIMER_Object_t timerSendData;
/* random delay to make sure 2 devices will sync*/
/* the closest the random delays are, the longer it will
take for the devices to sync when started simultaneously*/
static int32_t random_delay;
//????
static int16_t temp_v=0;
static uint16_t bat_v=0;
static uint16_t pa11_v=0;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
/*!
* @brief Function to be executed on Radio Tx Done event
*/
static void OnTxDone(void);
/**
* @brief Function to be executed on Radio Rx Done event
* @param payload ptr of buffer received
* @param size buffer size
* @param rssi
* @param LoraSnr_FskCfo
*/
static void OnRxDone(uint8_t *payload, uint16_t size, int16_t rssi, int8_t LoraSnr_FskCfo);
/**
* @brief Function executed on Radio Tx Timeout event
*/
static void OnTxTimeout(void);
/**
* @brief Function executed on Radio Rx Timeout event
*/
static void OnRxTimeout(void);
/**
* @brief Function executed on Radio Rx Error event
*/
static void OnRxError(void);
/* USER CODE BEGIN PFP */
/**
* @brief Function executed on when led timer elapses
* @param context ptr of LED context
*/
static void OnSendDataEvent(void *context);
/**
* @brief PingPong state machine implementation
*/
static void SendData_Process(void);
static char ReadSHT3x(float *Hum,float *Temp);
static uint8_t SHT3x_CRC_CAL(uint16_t DAT);
/* USER CODE END PFP */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
switch (GPIO_Pin)
{
case 1:
/* Note: when "EventType == TX_ON_TIMER" this GPIO is not initialized */
APP_LOG(TS_OFF, VLEVEL_M, "\n\rBUT1 Event\n\r");
break;
default:
break;
}
}
/* Exported functions ---------------------------------------------------------*/
void SubghzApp_Init(void)
{
/* USER CODE BEGIN SubghzApp_Init_1 */
/* Print APP version*/
/*???????*/
UTIL_TIMER_Create(&timerSendData, 0xFFFFFFFFU, UTIL_TIMER_ONESHOT, OnSendDataEvent, NULL);
/*??????*/
UTIL_TIMER_SetPeriod(&timerSendData, SEND_PERIOD_MS);
/*????*/
UTIL_TIMER_Start(&timerSendData);
/* USER CODE END SubghzApp_Init_1 */
/* Radio initialization */
RadioEvents.TxDone = OnTxDone;
RadioEvents.RxDone = OnRxDone;
RadioEvents.TxTimeout = OnTxTimeout;
RadioEvents.RxTimeout = OnRxTimeout;
RadioEvents.RxError = OnRxError;
/*?????*/
Radio.Init(&RadioEvents);
/*??????*/
Radio.SetChannel(RF_FREQUENCY);
/* Radio configuration */
APP_LOG(TS_OFF, VLEVEL_M, "---------------\n\r");
APP_LOG(TS_OFF, VLEVEL_M, "LORA_MODULATION\n\r");
APP_LOG(TS_OFF, VLEVEL_M, "LORA_BW=%d kHz\n\r", (1 << LORA_BANDWIDTH) * 125);
APP_LOG(TS_OFF, VLEVEL_M, "LORA_SF=%d\n\r", LORA_SPREADING_FACTOR);
/*??????*/
Radio.SetTxConfig(MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH,
LORA_SPREADING_FACTOR, LORA_CODINGRATE,
LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON,
true, 0, 0, LORA_IQ_INVERSION_ON, TX_TIMEOUT_VALUE);
/*??????*/
Radio.SetRxConfig(MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR,
LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH,
LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON,
0, true, 0, 0, LORA_IQ_INVERSION_ON, true);
/*????????*/
Radio.SetMaxPayloadLength(MODEM_LORA, MAX_APP_BUFFER_SIZE);
/* LED initialization*/
compute_train_stats();
/* ?? initialization*/
BSP_PB_Init(BUTTON_SW1, BUTTON_MODE_EXTI);
/*calculate random delay for synchronization*/
random_delay = (Radio.Random()) >> 22; /*10bits random e.g. from 0 to 1023 ms*/
/*fills tx buffer*/
memset(BufferTx, 0x0, MAX_APP_BUFFER_SIZE);
APP_LOG(TS_ON, VLEVEL_L, "rand=%d\n\r", random_delay);
/*starts reception*/
//Radio.Rx(RX_TIMEOUT_VALUE + random_delay);
/*register task to to be run in while(1) after Radio IT*/
/* ????*/
UTIL_SEQ_RegTask((1 << CFG_SEQ_Task_SubGHz_Phy_App_Process), UTIL_SEQ_RFU, SendData_Process);
/* USER CODE END SubghzApp_Init_2 */
}
/* USER CODE BEGIN EF */
/* USER CODE END EF */
/* Private functions ---------------------------------------------------------*/
/* ??????*/
static void OnTxDone(void)
{
/* USER CODE BEGIN OnTxDone */
/* Update the State of the FSM*/
State = S_TX;
/* Run PingPong process in background*/
UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_SubGHz_Phy_App_Process), CFG_SEQ_Prio_0);
/* USER CODE END OnTxDone */
}
/* ??????*/
static void OnRxDone(uint8_t *payload, uint16_t size, int16_t rssi, int8_t LoraSnr_FskCfo)
{
/* USER CODE BEGIN OnRxDone */
APP_LOG(TS_ON, VLEVEL_L, "OnRxDone\n\r");
APP_LOG(TS_ON, VLEVEL_L, "RssiValue=%d dBm, SnrValue=%ddB\n\r", rssi, LoraSnr_FskCfo);
/* Update the State of the FSM*/
State = S_RX;
/* Clear BufferRx*/
memset(BufferRx, 0, MAX_APP_BUFFER_SIZE);
/* Record payload size*/
RxBufferSize = size;
if (RxBufferSize <= MAX_APP_BUFFER_SIZE)
{
memcpy(BufferRx, payload, RxBufferSize);
}
/* Record Received Signal Strength*/
RssiValue = rssi;
/* Record payload content*/
APP_LOG(TS_ON, VLEVEL_H, "payload. size=%d \n\r", size);
for (int i = 0; i < PAYLOAD_LEN; i++)
{
APP_LOG(TS_OFF, VLEVEL_H, "%02X", BufferRx[i]);
if (i % 16 == 15)
{
APP_LOG(TS_OFF, VLEVEL_H, "\n\r");
}
}
APP_LOG(TS_OFF, VLEVEL_H, "\n\r");
/* Run PingPong process in background*/
UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_SubGHz_Phy_App_Process), CFG_SEQ_Prio_0);
/* USER CODE END OnRxDone */
}
/* ??????*/
static void OnTxTimeout(void)
{
/* USER CODE BEGIN OnTxTimeout */
APP_LOG(TS_ON, VLEVEL_L, "OnTxTimeout\n\r");
/* Update the State of the FSM*/
State = S_TX_TIMEOUT;
/* Run PingPong process in background*/
UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_SubGHz_Phy_App_Process), CFG_SEQ_Prio_0);
/* USER CODE END OnTxTimeout */
}
/* ??????*/
static void OnRxTimeout(void)
{
/* USER CODE BEGIN OnRxTimeout */
APP_LOG(TS_ON, VLEVEL_L, "OnRxTimeout\n\r");
/* Update the State of the FSM*/
State = S_RX_TIMEOUT;
/* Run PingPong process in background*/
UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_SubGHz_Phy_App_Process), CFG_SEQ_Prio_0);
/* USER CODE END OnRxTimeout */
}
/* ??????*/
static void OnRxError(void)
{
/* USER CODE BEGIN OnRxError */
APP_LOG(TS_ON, VLEVEL_L, "OnRxError\n\r");
/* Update the State of the FSM*/
State = S_RX_ERROR;
/* Run PingPong process in background*/
UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_SubGHz_Phy_App_Process), CFG_SEQ_Prio_0);
/* USER CODE END OnRxError */
}
# define n 51.27
# define m -5.55
float change(int c)
{
float ph;
ph=(c-n)/m;
return ph;
}
int i=0;
int k;
void process_calibrated_data(void)
{
// ͳ¼ÆÖ÷ÒªÐÐΪ£¨±£Áô£©
uint8_t counts[4] = {0};
for(int i=0; i<SAMPLES_TO_COLLECT; i++) {
counts[prediction_results[i]]++;
}
uint8_t max_label = 0;
for(int i=0; i<4; i++) {
if(counts[i] > counts[max_label]) max_label = i;
}
printf("Dominant Behavior: %d\n", max_label);
int16_t input_features[SAMPLES_TO_COLLECT][3];
/* ת»»ÎªKNNÊäÈë¸ñʽ */
for(int i=0; i<SAMPLES_TO_COLLECT; i++){
input_features[i][0] = calibrated_samples[i][0];
input_features[i][1] = calibrated_samples[i][1];
input_features[i][2] = calibrated_samples[i][2];
}
/* Ö´ÐÐÔ¤²â²¢Í³¼Æ×¼È·¶È */
uint8_t correct_count = 0;
for(int i=0; i<SAMPLES_TO_COLLECT; i++){
uint8_t pred = predict_class(input_features[i]);
prediction_results[i] = pred;
/* Óëʵ¼Ê±êÇ©±È½Ï£¨ÕâÀïÐèÒª¸ù¾Ýʵ¼ÊÇé¿öÐ޸ģ© */
if(pred == dataset[i].label) correct_count++;
}
/* Êä³ö½á¹û */
float accuracy = (float)correct_count/SAMPLES_TO_COLLECT*100;
printf("Prediction Accuracy: %.1f%%\n", accuracy);
}
static uint8_t sample_count = 0;
// ¶¨ÒåÒ»¸öÊý×éÀ´´æ´¢Ð£×¼ºóµÄÊý¾Ý
#define SAMPLE_BUFFER_SIZE 10
static Vector1 sample_buffer[SAMPLE_BUFFER_SIZE];
static uint8_t buffer_index = 0;
static void SendData_Process(void)
{
switch (State)
{
case S_IDLE:
case S_TXing:
break;
case S_RX:
Radio.Sleep();
State = S_IDLE;
break;
case S_TX:
Radio.Sleep();
State = S_IDLE;
break;
case S_RX_TIMEOUT:
case S_RX_ERROR:
case S_TX_TIMEOUT:
Radio.Sleep();
State = S_IDLE;
break;
case S_SEND_DATA:
{
MPU6050_Init();
int16_t AX, AY, AZ;
for(int rain=0; rain<10; rain++)
{
MPU6050_GetData(&AX, &AY, &AZ);
AX = AX/4 * 0.976;
AY = AY/4 * 0.976;
AZ = AZ/4 * 0.976;
BufferTx[5+6*rain] = (AX < 0) ? 1 : 0;
BufferTx[6+6*rain] = abs(AX)/100;
BufferTx[7+6*rain] = (AY < 0) ? 1 : 0;
BufferTx[8+6*rain] = abs(AY)/100;
BufferTx[9+6*rain] = (AZ < 0) ? 1 : 0;
BufferTx[10+6*rain] = abs(AZ)/100;
printf("%d ",AX);
printf("%d ",AY);
printf("%d\n",AZ);
/* ´«¸ÐÆ÷У׼ */
Vector1 raw_data = {AX, AY, AZ};
Vector1 calib_data = solve(raw_data);
/* ´æ´¢µ½»º³åÇø */
if(buffer_index < SAMPLE_BUFFER_SIZE)
{
sample_buffer[buffer_index] = calib_data;
buffer_index++;
}
printf("Sample %d: %.2f, %.2f, %.2f\n",
buffer_index,
calib_data.x,
calib_data.y,
calib_data.z);
}
/* µ±ÊÕ¼¯Âú10×éÊý¾Ýʱ½øÐÐÔ¤²â */
if(buffer_index >= SAMPLE_BUFFER_SIZE)
{
/* ת»»Êý¾Ý¸ñʽ¹©KNNʹÓà */
int16_t knn_input[SAMPLE_BUFFER_SIZE][3];
for(int i=0; i<SAMPLE_BUFFER_SIZE; i++)
{
knn_input[i][0] = (int16_t)(sample_buffer[i].x);
knn_input[i][1] = (int16_t)(sample_buffer[i].y);
knn_input[i][2] = (int16_t)(sample_buffer[i].z);
}
/* Ö´ÐÐÔ¤²â²¢Í³¼ÆÆ±Êý */
uint8_t votes[4] = {0}; // [0]:±êÇ©0µÄƱÊý£¬[1]:±êÇ©1...
for(int i=0; i<SAMPLE_BUFFER_SIZE; i++)
{
uint8_t label = predict_class(knn_input[i]);
BufferTx[75] = label;
votes[label]++;
}
/* аæÍ¶Æ±Âß¼ */
uint8_t final_label = 0;
const uint8_t zero_votes = votes[0]; // ±êÇ©0µÄƱÊý
// Ìõ¼þ1£º0µÄƱÊý¡Ý9ʱֱ½Ó·µ»Ø0
if(zero_votes >= 9) {
final_label = 0;
}
// Ìõ¼þ2£ºÅųý0ºó±È½ÏÆäËû±êÇ©
else {
// ³õʼ»¯ÎªµÚÒ»¸ö·ÇÁã±êÇ©
final_label = 1;
uint8_t max_votes = votes[1];
// ±éÀú±êÇ©1-3ÕÒ×î´óÖµ
for(uint8_t label=2; label<=3; label++){
if(votes[label] > max_votes){
final_label = label;
max_votes = votes[label];
}
// ƽƱʱѡÔñ±àºÅСµÄ±êÇ©
else if(votes[label] == max_votes && label < final_label){
final_label = label;
}
}
// ´¦ÀíÈ«ÁãµÄÌØÊâÇé¿ö£¨ÀíÂÛÉϲ»»á³öÏÖ£©
if(max_votes == 0){
final_label = 0; // ½µ¼¶·µ»Ø0
}
}
printf("Final Prediction: %d\n", final_label);
/* ÖØÖûº³åÇø */
buffer_index = 0;
memset(sample_buffer, 0, sizeof(sample_buffer));
}
/* ·¢ËÍÔʼÊý¾Ý£¨±£³ÖÔÓÐÂß¼£© */
BufferTx[0] = 5;//¶ÔÓ¦ÐòºÅ
MX_SPI2_Init();
uint16_t ADCXX=0x00;
uint8_t i=0;
int ADCX=0;
ADS1120reset();
HAL_Delay(20);
ADCXX = ADS1120readonce();
if(ADCXX>32767)
{ADCXX=3.15*(65534-ADCXX)/100;
ADCX=ADCX-ADCXX;
HAL_Delay(10);
}
if(ADCXX<32767)
{ADCXX=3.15*ADCXX/100;
ADCX=ADCX+ADCXX;
HAL_Delay(10);
}
if(ADCXX==32767)
{
HAL_Delay(10);
}
ADCX=ADCX/50;
printf("%d\r\n",ADCX);
float a;
a=change(ADCX);
printf("%1.1f\r\n",a);
SHT3x_Init();
float Temp,Hum; //
if(ReadSHT3x(&Hum,&Temp)) //
{
if(Temp>=0)
{
printf("%.2f\n", Temp);//
}
else
{
printf("%.2f\n", Temp);//
}
}
else
{printf("error");}
int zhengshu,xiaoshu;
zhengshu=Temp*100/100;
xiaoshu=Temp*100;
xiaoshu=xiaoshu%100;
BufferTx[1]=zhengshu;
BufferTx[2]=xiaoshu;
a=a*10;
int b,c;
b=(int)a/10;
c=(int)a%10;
c=c+1;
BufferTx[3]=b;
BufferTx[4]=c;
Radio.Send(BufferTx, 80);
State = S_TXing;
break;
}
break;
default:
break;
}
}
static void OnSendDataEvent(void *context)
{
// BSP_LED_On(LED_GREEN);
// BSP_LED_On(LED_RED);
UTIL_TIMER_Start(&timerSendData);
if(State == S_IDLE)
{
State = S_SEND_DATA;
UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_SubGHz_Phy_App_Process), CFG_SEQ_Prio_0);
}
else
{
APP_PRINTF("OnSendDataEvent Error State(%d)\n\r",State);
}
}
static char ReadSHT3x(float *Hum,float *Temp)
{
uint16_t HumData,TempData,HumCRC,TempCRC;//???????????
// SHT3x_WriteByte(0XE0,0X00); //????,????,?????????
SHT3x_WriteByte(0X2C,0X0D); //????????(??????,Medium Repeatability)
SHT3x_I2C_START(); //??????
SHT3x_I2C_SendByte(SHT3x_ADDRESS|0x01);//???????
WaitAck();
SHT3x_W_SCL(1); //??SCL??
while (!SHT3x_R_SCL())
; //??????SCL??
TempData = SHT3x_ReadData(0); //?????8???
TempData=TempData<<8; //??8?
// int c;
// c=SHT3x_ReadData(0);
TempData |= SHT3x_ReadData(0); //?????8???
TempCRC = SHT3x_ReadData(0); //????CRC????
HumData = SHT3x_ReadData(0); //?????8???
HumData=HumData<<8; //??8?
HumData |= SHT3x_ReadData(0); //?????8???
HumCRC = SHT3x_ReadData(1); //????CRC????
SHT3x_I2C_STOP(); //??????
if( SHT3x_CRC_CAL(HumData)==HumCRC && SHT3x_CRC_CAL(TempData)==TempCRC ){ //????????CRC??
*Hum = (float)HumData*100/(65536-1); //????16?????????10??????
// *Temp=(-45+(175.0*((TempData<<8)+c)/65535.0))*100;
//
*Temp = (float)TempData*175/(65536-1)-45; //????16?????????10??????
return 1;
}
return 0;
}
static uint8_t SHT3x_CRC_CAL(uint16_t DAT)
{
uint8_t i,t,temp;
uint8_t CRC_BYTE;
CRC_BYTE = 0xFF;
temp = (DAT>>8) & 0xFF;
for(t = 0; t < 2; t++)
{
CRC_BYTE ^= temp;
for(i = 0;i < 8;i ++)
{
if(CRC_BYTE & 0x80)
{
CRC_BYTE <<= 1;
CRC_BYTE ^= 0x31;
}
else
{
CRC_BYTE <<= 1;
}
}
if(t == 0)
{
temp = DAT & 0xFF;
}
}
return CRC_BYTE;
} 将knn改为支持向量机算法
最新发布