分类目录归档:Embedded System

ESP32+Arduino的smartconfig配网方式,以及配套APP

主要原理采用了WIFI UDP发送广播的方式
由于Arduino提供的驱动包实在太方便了,这里直接用了,可以去看一下库源码,源码的继承关系还是比较多了,一个WIFI类继承了多个不同的父类,其中ESP8266WiFiSTAClass类提供了在STA模式下的各种方法,这里面就有

        bool beginWPSConfig(void);
        bool beginSmartConfig();
        bool stopSmartConfig();
        bool smartConfigDone();四个方法,WPS需要路由器支持,其他三个方法看名字就知道用途
demo代码如下:
 
char ssid[30] = STASSID;
char password[30] = STAPSK;
//以下函数在setup中调用
void smartConfig()
{
  WiFi.mode(WIFI_STA);//切换到STA模式
  Serial.println(“\r\nWait for Smartconfig\r\n”);
  WiFi.beginSmartConfig();//开始smartconfig
  while (1)
  {
    Serial.print(“Waiting …\r\n”);
    if (WiFi.smartConfigDone())
    {
      Serial.println(“SmartConfig Success!!!”);
      Serial.printf(“SSID:%s\r\n”, WiFi.SSID().c_str());
      Serial.printf(“PSW:%s\r\n”, WiFi.psk().c_str());
      memset(ssid,0,sizeof(ssid));
      memset(password,0,sizeof(password));
      sprintf(ssid,”%s”,WiFi.SSID().c_str());
      sprintf(password,”%s”,WiFi.psk().c_str());        //设置WIFI账号和密码
      WiFi.setAutoConnect(true);                        //设置自动连接
      break;
    }
    delay(1000);
  }
}
 
 
昨天找了半天的配网工具,其实乐鑫官方就提供了一个很好用的esp-touch
需要先把手机连接到wifi上,然后通过UDP广播,ESP32才可以收到数据包
 
网上各种配网软件乱七八糟的,这个软件在很多手机的应用商店没有上架,所以还是要去乐鑫的官网下载。

MAX30102使用方式记录

最近做一个小项目,需要使用到MAX30102检测用户的心率数据,然而网上普遍没有什么教程,大概看了一下官方给的arduino示例程序。

示例程序地址:https://github.com/MaximIntegratedRefDesTeam/RD117_ARDUINO/blob/master/RD117_ARDUINO.ino

大概分析了一下,这个传感器用的是IIC协议,初始化的时候需要用IIC协议往几个寄存器里面写一些数据,这样就算是初始化了,传感器需要连接的针脚主要有VIN GND SDA SCL INT,VIN是电源,官方说的是5V,实测3.3也可以工作,SDA和SCL是IIC线,INT是一个类似状态引脚的东西,接下来从传感器读取数据的时候需要用。

传感器的原理大概就是用红外光反射检测波长来判断用户的心率,传感器可以检测返回的波长,做AD转换转换成电数据,但是没什么计算单元,所以我们从传感器的FIFO里面获取到这些数据之后,需要自己来根据这些原始的数据来计算。

计算的过程比较复杂,不过官方给的示例代码里面给出了计算的库,我们直接调用函数就可以了,大概就是把两个采样数据的buffer指针穿进去,一个参数说明用多少个采样来计算。输出的结果就是根据这些采的数据计算出的心率(HR)和血氧(SPO2),还有是否有效标记,如果标记=0说明样本是无效的,也就不能给出正确的心率和血氧。

官方给的实例代码思路大概是这样的:

读取前5秒钟的采样数据(采样速率是100样本/s,一共500个样本)
计算这500个样本的数据结果();
while(1)
{
  丢弃第一秒的前100个样本,剩下400个样本();
  采一秒钟的样本(100个);
  把新的样本数据和旧的样本数据结合(现在有500个);
  计算心率和血氧
}

这样在这个大循环里面,每秒钟都会有新的采样值,新的采样值结合前四秒钟的数据,给出当前的心率。这就是心率采样的大概思路。具体的操作和寄存器说明我还没看DataSheet,需要看一看再说。

STM32中TIM定时器中断的一个细节问题记录

今天调试的时候发现,当使用TIM定时器作为计时器使用的时候,TIM定时器的中断服务函数第一次执行,是在TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE );语句后就开始执行的,而不是到达第一个计数周期的时候。

这对仅利用一次定时器的程序有一定影响。

 

void TIM4_Int_Init(u16 period,void (*__TIM4_IRQHandler_Inside__)(void))
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    RCC_ClocksTypeDef RCC_ClocksStatus;
    uint16_t prescaler;         
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); 
    RCC_GetClocksFreq(&RCC_ClocksStatus);
    prescaler = RCC_ClocksStatus.SYSCLK_Frequency / 1000000 ;       
    TIM_TimeBaseStructure.TIM_Period = period-1;                                    //ÉèÖÃÔÚÏÂÒ»¸ö¸üÐÂʼþ×°Èë»î¶¯µÄ×Ô¶¯ÖØ×°ÔؼĴæÆ÷ÖÜÆÚµÄÖµ     ¼ÆÊýµ½5000Ϊ5000ms
    TIM_TimeBaseStructure.TIM_Prescaler =(prescaler*1000)-1;            //ÏÖÔÚÿ´Î+1ÊÇ1ms 32000·ÖƵ  32000000/32000=1000 ÿÃëÖÓ¸üÐÂ1000´Î£¬Ã¿´Î¸üÐÂÊÇ1ms
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;                                    //ÉèÖÃʱÖÓ·Ö¸î:TDTS = Tck_tim
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;     
    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);                             //¸ù¾ÝTIM_TimeBaseInitStructÖÐÖ¸¶¨µÄ²ÎÊý³õʼ»¯TIMxµÄʱ¼ä»ùÊýµ¥Î»
print_d("1\n");
    TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE ); 
    
    NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;  
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
    NVIC_Init(&NVIC_InitStructure);  
print_d("2\n");
    TIM4_IRQHandler_Inside=__TIM4_IRQHandler_Inside__;
    TIM_Cmd(TIM4, ENABLE); 
print_d("3\n");
    EXTIstatus.Tim4IsUsing=1;
    print_d("TIM4 init finished\n");
}

串口调试输出: 继续阅读