技能梳理11@onenet+避障小车+oled+nodemcu+stm32

294 阅读3分钟

onenet控制小车,自动红外避障,远程控制小车上一个电机清扫,一个电机吸尘,两个电机前进;oled屏显示电量和小车状态

1、项目简介

在这里插入图片描述

2、实现逻辑

#stm32负责红外避障、oled显示状态、adc检测电量、进行各个电机的pwm控制等
#nodemcu连接到onenet后负责进行状态的上行和控制指令的下发中转

3、应用场景

#远程清洁卫生

4、核心代码梳理

void clean_start()
{
	  __HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,100);
		HAL_Delay(500);
		__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,150);
		HAL_Delay(500);
		__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,200);
}

void run_start(uint8_t front, uint8_t right)
{
	static uint8_t stop_cnt;
#define C  2
#define PWM  1800
#define CHA  20
	
	if(front == STOP)
	{
		stop_cnt++;
		if(stop_cnt > 30)
		{
			stop_cnt = 0;
			__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_1,PWM); //1800 - 50% pwm 2+  1-  run
		    __HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_2,0);
		    __HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_3,PWM-CHA);
		    __HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_4,0);
			HAL_Delay(2000); //2s
			__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_1,0); //1800 - 50% pwm 2+  1-  run
		    __HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_2,PWM/C);
		    __HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_3,0);
		    __HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_4,PWM);
			HAL_Delay(1000); //ǰ2s
		}
	}
	
	if(front == RUN)
	{
		__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_1,0); //1800 - 50% pwm 2+  1-  run
		__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_2,PWM);
		__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_3,0);
		__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_4,PWM-CHA);
		stop_cnt = 0;
	}
	else if(right == RUN)
	{
		__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_1,0); //1800 - 50% pwm 2+  1-  run
		__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_2,PWM);
		__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_3,0);
		__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_4,PWM/C);
	}
	else if(right == STOP)
	{
		__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_1,0); //1800 - 50% pwm 2+  1-  run
		__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_2,PWM/C);
		__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_3,0);
		__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_4,PWM);
	}

}
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
    uint8_t cnt;
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  MX_ADC1_Init();
  MX_TIM1_Init();
  MX_TIM4_Init();
  /* USER CODE BEGIN 2 */
    tx_onenet[0] = 0xff;
    tx_onenet[1] = 0x74;
    tx_onenet[13] = 0xff;
    __HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE);//open uart1 RXNE
    HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1 );
    HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_1 );
    HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_2 );
    HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_3 );
    HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_4 );
	clean_start();
	HAL_TIM_PWM_Stop(&htim1,TIM_CHANNEL_1 );
		
	OLED_Init();
    OLED_ColorTurn(0);//
    OLED_DisplayTurn(0);//
    OLED_Refresh();
    OLED_Clear();
    OLED_ShowString(0,0,"VOLT:    .    %",16);
    OLED_ShowString(0,14,"STA:      ",16);
	OLED_ShowString(0,28,"0-OFF 1-ON",16);
    OLED_Refresh();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
    while (1)
    {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
        HAL_GPIO_TogglePin(GPIOC, LED_Pin);
        cnt++;
			
		HAL_ADC_Start_IT(&hadc1);
		HAL_Delay(200);
        if((cnt%20 == 0) || (rx_ok))
        {
            rx_ok = 0;
            Vrl = (ADC_num * 825)/1024; 
					
			Vrl = (Vrl-1300) *100 / (2900-1300);  //ٷֱ
			if(Vrl < 0)
				Vrl = 0;
			else if(Vrl > 100)
				Vrl = 100;
            uint8_t shi = Vrl;
            tx_onenet[2] = shi;
            tx_onenet[3] = (Vrl-shi)*100;
            tx_onenet[4] = order;
            HAL_UART_Transmit(&huart1, (uint8_t *)tx_onenet, 14, 0xFFFF);
        }
				if(order)
				{
					HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);
					run_start(HAL_GPIO_ReadPin(GPIOB,IFR_F_Pin), HAL_GPIO_ReadPin(GPIOB,IFR_B_Pin));
					HAL_GPIO_WritePin(ctr_mos_GPIO_Port, ctr_mos_Pin, GPIO_PIN_SET);
				}
				else
				{
					HAL_TIM_PWM_Stop(&htim1,TIM_CHANNEL_1);
					__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_1,0); //1800 - 50% pwm 2+  1-  run
					__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_2,0);
					__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_3,0);
					__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_4,0);
					HAL_GPIO_WritePin(ctr_mos_GPIO_Port, ctr_mos_Pin, GPIO_PIN_RESET);
				}
				
				//OLED
				
		OLED_ShowNum(53,14,order,1,16); //STA
        OLED_ShowNum(53,0,tx_onenet[2],2,16);//VOLT
        OLED_ShowNum(77,0,tx_onenet[3],2,16);
        OLED_Refresh();
    }
  /* USER CODE END 3 */
}


//lua脚本
VOLAT = 0
ORDER = 0
cnt = 0

pin=4
gpio.mode(pin,gpio.OUTPUT)


cfg = {}
cfg.ssid = "test"
cfg.pwd = "123456789"
 
myClient = mqtt.Client(DeviceId, KeepAlive, ProductId, AuthoTnfo)
--print("115200 8-n-1")
uart.setup(0, 115200, 8, uart.PARITY_NONE, uart.STOPBITS_1, 0)

timer1 = tmr.create()

timer2 = tmr.create()
 
function ReConnect()
    if wifi.sta.getip() == nil then
        print("Connect AP,waitting...")
    else
        print("Connected AP,Success!")
        --print("IP is:"..wifi.sta.getip())
        --print("MAC address:"..wifi.sta.getmac())
        timer1:stop()
 
        myClient:connect(host, port, function(client)
           -- print("Connected OneNET success!")
            gpio.write(pin,gpio.LOW)  
        end)
         
       
        uart.on("data", function(data)   
            cnt = string.len(data) 
            timer1.stop(1)
            timer1.interval(1, 1)   
            timer1.start(1)  
            --uart.write(0, data) 
            print("len:",cnt)  
            --print(type(data))
            if(cnt == 13) then
                cnt = 0
                if(string.find(data,"t") == 1) then
                    --print("t!") 
                    --print(string.byte(data,2))
                    --print(string.byte(data,3)/100)
                    VOLAT = string.byte(data,2) + string.byte(data,3)/100
                    ORDER = string.byte(data,4)
                end
            end
            Update_Message()
        end, 0)
         
        myClient:on("message", function(client , topic , message)
            --print("get a message.\n")
            --print(topic..":"..message)
        print("order:"..message)
        end) 
  
        --timer2:alarm(3000, tmr.ALARM_AUTO, Update_Message)
    end
end 
  
timer1:alarm(1000,tmr.ALARM_AUTO,ReConnect)
   

     
function Update_Message()
    info = {}
    info.volat = VOLAT
    info.order = ORDER

    ok,message = pcall(cjson.encode, info)
    --print("message:"..message)
 
    header = string.char(3, 0 ,string.len(message))..message
    myClient:publish("$dp", header, 0, 0, function(client)
        --print("Publish info success!")
    end)
end

5、部分参考资料

#nodemcu主控是esp8266
#lua编程

6、注意事项

#电机不适宜选比较大的,电池带不动
#吸尘电机淘宝上买的,几块钱可以吸尘
#吸尘电机启停的时候电量会有变化
#清扫电机用360度舵机就行,清扫速度控制
#电机是12v供电,采集电压前要分压到3.3v以内

完整可运行项目地址