资讯详情

软硬件全开源,航芯方案分享 | 智能电动牙刷方案

当代口腔问题频发,使人们越来越重视口腔卫生。由于个人习惯和刷牙方法的不同,传统的刷牙方法会不同程度地导致牙龈损伤、牙菌斑去除不彻底等问题。而电动牙刷设备,基于其相对程序化的刷牙方式,可根据个人口腔特点支持独立选择,调整刷牙强度。而且在刷牙的过程中,不需要太多的手动作,只需要调整刷牙的角度,更多的清洁工作由牙刷本身的特点交付。方便人们,也能有效减少口腔问题。

目前市场上电动牙刷种类繁多,刷头可分为旋转式和振动式(又称声波式)两类。https://zhuanlan.zhihu.com/p/...

图1. 电动牙刷工作模式比较图

旋转电动牙刷由电机驱动刷头旋转,牙齿表面清洁度高,但牙齿清洁能力弱,比振动更容易损坏牙釉质。振动,由电机驱动刷头上下高频振动,高频摆动刷头可以有效地完成刷牙的动作,可以使牙膏和水的混合物产生大量的小气泡,气泡爆裂产生的压力可以深入牙齿,达到深层清洁效果。

实现振动有两种方式,一种是由偏心振动电机实现的,主要用于中低档电动牙刷方案。这样,电动牙刷振动感强,振动无序。另一种是线性电机,在业内也被称为磁悬浮电机。

图2. 磁悬浮电机示意图

磁悬浮电机的优点是工作噪音低,机身振动低,振动能集中,清洁效果好。因此,本文采用了这一点ACM32F作为主控芯片,030提出了基于磁悬浮电机的电动牙刷设计方案。

基于上海航芯的电动牙刷方案ACM32F030系列的MCU整体方案框图如下:

图3. 基于ACM32F030/070电动牙刷设计方案框图

ACM32F0X0 该系列是支持各种低功耗模式的通用系列MCU。集成12位1.6 Msps高精度ADC还有比较器、运输、触摸按钮控制器LCD内置高性能定时器、多路控制器UART、LPUART、SPI、I2C通信外设等丰富,内建AES、TRNG支持多种低功耗模式的信息安全模块,具有集成度高、抗干扰性高、可靠性高的特点。本产品采用ARM Cortex-M0系列内核,最高工作频率64MHz。满足一般电动牙刷方案的需要。

扫码即可立即购买ACM32F070KBU7 备注:ACM32F030和070软硬件兼容

扫描代码可以立即购买开发板

软硬件下载链接如下:

https://gitee.com/acm32-mcu/e...https://github.com/ACM32-MCU/...

本文讨论中的人机交互功能简单LED实现按键的方式。有一个按钮和六个按钮LED。按键需实现设备的开关机以及模式切换功能。根据按钮按下时间的长短,设备将确定当前动作是否需要切换模式或开关操作。6个LED本设计方案仅提供三种工作模式指示,最大可支持7种工作模式(23-1)。另外3个LED用于系统状态指示,包括正常、欠压、充电和四种电压状态。

长度按识别程序:

void keyPressHandler(void) {   key.isPressed = Key_GetPressValue();   switch(key.pressState)   {     case 0:       if(key.isPressed)       {         key.pressTime = 0;         key.pressState = 1;       }       break;     case 1:    /*  eliminate jitter  */       if(key.isPressed)       {         if(  key.pressTime > 10)           key.pressState = 2;       }       else         key.pressState = 0;       break;     case 2:    /*  whether long press is existed  */       if(key.isPressed)       {         if(  key.pressTime > LONG_PRESS_TIME)           key.pressState = 3;       }       else       {         if(key.shortPressHandler != NULL)           key.shortPressHandler();         else           DEBUG_KEY("have no short press handler!= NULL)           key.shortPressHandler();         else           DEBUG_KEY("have no short press handler!!\r\n");         key.pressState = 0;       }       break;     case 3:       if(key.longPressHandler != NULL)         key.longPressHandler();       else         DEBUG_KEY("have no long press handler!!\r\n");       key.pressState = 4;       break;     case 4:    /*  wait for releasing key  */       if(key.isPressed == 0)         key.pressState = 0;       break;   } }

void appMotorModeLedControl(void) {   static uint8_t state = 0xFF;      if(sys.status == SYSTEM_RUNMODE)   {     if(state != sys.motorStatus)     {       state = sys.motorStatus;       if(sys.motorStatus == 0)       {         ModeLed_Select(MODE_LED_1, MODE_LED_ON);       }       else if(sys.motorStatus == 1)       {         ModeLed_Select(MODE_LED_2, MODE_LED_ON);       }       else if(sys.motorStatus == 2)       {         ModeLed_Select(MODE_LED_3, MODE_LED_ON);       }     }   }   else   {     state = 0xFF;     ModeLed_Select(MODE_LED_UNKNOWN, MODE_LED_OFF);   } }

void appSysLedController(void) {   static uint8_t led_state = 0xFF;      if(led_state != led.state)   {     led_state = led.state;     if(led.state == LED_OFF)     {       led.duty = 0;       PowerLed_Select(PWR_LED_UNKNOWN, PWR_LED_OFF);       PWM_dutySet(PWM_LED, led.duty);     }     else if(led.state == LED_TWINKLE)    // low power warning     {       led.duty = 0;       PowerLed_Select(PWR_LED_R, PWR_LED_ON);       PWM_dutySet(PWM_LED, led.duty);     }     else if(led.state == LED_ON)     {       led.duty = 0;       PowerLed_Select(PWR_LED_R, PWR_LED_OFF);       PWM_dutySet(PWM_LED, led.duty);     }     else if(led.state == LED_BREATHE)     {       if(led.duty == PWM_DUTY_MAX)         led.dir = LED_FADE;       else         led.dir = LED_BRIGHTER;     }     else       led.state = LED_OFF;   }   else{     if(led.state == LED_BREATHE)     {       PowerLed_Select(PWR_LED_UNKNOWN, PWR_LED_OFF);       if(led.dir == LED_BRIGHTER)       {         if(led.duty < PWM_DUTY_MAX)           led.duty  = BREATHE_INTERVAL;         else         {           if(  led.cnt > BREATHE_HOD_TIME)
          {
            led.dir = LED_FADE;
            led.cnt = 0;
          }
        }
      }
      else
      {
        if(led.duty > BREATHE_INTERVAL)
          led.duty -= BREATHE_INTERVAL;
        else
        {
          led.duty = 0;
          if(++led.cnt > BREATHE_HOLD_TIME)
          {
            led.dir = LED_BRIGHTER;
            led.cnt = 0;
          }
        }
      }
      PWM_dutySet(PWM_LED, led.duty);
    }
  }
}

电动牙刷产品的续航能力也是一直备受人们关注。本设计方案在低功耗的处理,摒弃了一般的休眠方式,直接采用关闭电源来避免设备在不工作状态下的设备功耗。整个设备的供电线路共有三种,如下图所示。

图4. 基于ACM32F030的电动牙刷供电电路(部分)

正常情况下,设备不在充电时,VCHARG电压为0,需要关机时,按键弹开,PWR_KEY为低电平,芯片内部程序也将PWR_LOCK拉低,此时Q2关断,Q2的D极电压同VBAT,从而引起Q1断开,VCCIN断电,系统关机。而开机时,按键按下,PWR_KEY先被拉至高电平,Q2导通,Q2的D极拉低,则Q1导通,设备供电,程序检测到开机,拉高PWR_LOCK,此时,尽管按键弹开,PWR_LOCK仍然会提供Q2的导通电压,系统正常工作。充电时,Q2的导通电压会由VCHARG提供,系统保持在工作状态,此时会程序会检测系统的运行状态,在不需要启动时,进入休眠状态。

电源管理部分,则通过锂电池充电芯片检测是否进行充电,同时通过一路ADC监测电池电压。为减少芯片工作负担,电池电压的欠压和满电通过ADC门限电压功能来实现。ADC的门限电压初始化程序如下:

// ADC Watchdog config
  ADC_WDT_Handle.ITMode      = ENABLE;
  ADC_WDT_Handle.WatchdogMode  = ADC_ANALOGWATCHDOG_RCH_ALL;
  ADC_WDT_Handle.Channel      = channel;
  ADC_WDT_Handle.HighThreshold  = (HIGH_POWER_THS * 0x0FFF) / VREF ;
  ADC_WDT_Handle.LowThreshold  = (LOW_POWER_THS * 0x0FFF) / VREF ; 

智能管理系统分为两个部分,一部分为上位机的数据处理,由云端处理,另一部分是电动牙刷数据记录和传输。整个的实现过程可简述为,电动牙刷通过惯性测量仪QMI8658C记录电动牙刷在使用过程中的运动轨迹,并实时将该部分数据以及整个系统的工作参数通过BLE发送到手机,手机连接云端,并将数据传输至云平台进行数据解析,分析用户刷牙的健康指数,并将相关建议反馈至手机。电动牙刷作为数据采集设备,需上报实时数据,结构如下:

typedef __packed struct{
  uint32_t time;          // This shows the relative time of each activity
  uint16_t location[3];        // This shows the acceleration of brush when using
  uint16_t pressure;        // This is the force between tooth and brush
  uint16_t angle[3];        // This shows the angle between brush
  
}BLE_RealTimeDataDef;        // This define the data structure about brushing tooth in real time

其中,location为三轴的加速度,angle为三轴的角度。定时上传电动牙刷的相关实时数据。上位机根据一系列点位数据进行建模计算可得到整个牙刷的运动轨迹。

电动牙刷的驱动系统是通过H桥芯片MX612E进行处理,MX612E的输入端连接芯片的PWM互补输出端口。如下图所示:

图5. 电动牙刷电机驱动电路

本设计中的电动牙刷采用磁悬浮电机,内部构造和直流无刷电机相似,但相比于直流无刷电机,其仅有两相输入端。这也就造成该电机在通电后,正负极不变的情况下,电机旋转至某一角度形成平衡后将会停止旋转。切换正负极后则又会在另一个方向旋转形成平衡。在电动牙刷的正常工作中,是通过两相的正负极切换来使电机正反旋转从而带动刷头做高频运动的。因此,其电机速度的控制依靠于输出PWM的输出频率而非占空比。控制代码如下:

void PWM_freqSet(uint8_t PWMx, uint16_t freq)
{
  uint32_t arr;
  if(IS_PWM_INSTANCE(PWMx) == 0)  return;
  if(freq == 0)
  {
    TIM15->ARR = 0;
    return;
  }
  if(freq > PWM_FREQ_MAX)  freq = PWM_FREQ_MAX;
  if(freq < PWM_FREQ_MIN) freq = PWM_FREQ_MIN;
  arr = (PWM_TIMER_FRE / freq);
  if(PWMx == PWM_MOTOR)
  {
    TIM15->ARR = arr-1;
    TIM15->CCR1 = arr / 2;
  }
}

上例中,PWM的占空比为50%,使得在一个PWM周期内,电机可完成一次往返运动。

本文提出的设计方案的主旨是将电动牙刷智能化,在提高人们刷牙效率的同时,也能达到进一步保证人们刷牙质量的目的。通过电动牙刷对惯性的数据采集,实时上传至云端,并对数据进行处理,恢复用户的刷牙轨迹,给出合理建议,纠正用户不良的刷牙习惯。磁悬浮电机的高频振动也能有效清除口腔污渍。岁月恒久远,牙齿永相随 ^-^。

上海航芯·原厂直连:marketing@aisinochip.com

标签: 芯建集成电路

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

 锐单商城 - 一站式电子元器件采购平台  

 深圳锐单电子有限公司