• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
MKT-porter
博客园    首页    新随笔    联系   管理    订阅  订阅
(7)STM32开发例程 舵机和多路舵机驱动板
 
 
 

 1 直接驱动

180度塑料蓝色舵机

pb11不能用

#include <Servo.h>
 
Servo myservo;  // 定义Servo对象来控制

 
void setup() {
  myservo.attach(PA7);  // 控制线连接数字9
}
 
void loop() {

  myservo.write(90);    
  delay(3000);    
  myservo.write(0);
  delay(3000); 

}

  

2间接驱动、

 

 

2-1接线

B6 是 SCL,B7 是 SDA。

 

2-2 装库 

Adafruit_PWMServoDriver

 2-3 测试代码

1 自动扫描转动

/***************************************************
  This is an example for our Adafruit 16-channel PWM & Servo driver
  Servo test - this will drive 8 servos, one after the other on the
  first 8 pins of the PCA9685
 
  Pick one up today in the adafruit shop!
  ------> http://www.adafruit.com/products/815
   
  These drivers use I2C to communicate, 2 pins are required to 
  interface.
 
  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!
 
  Written by Limor Fried/Ladyada for Adafruit Industries. 
  BSD license, all text above must be included in any redistribution
 ****************************************************/
 
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
 
// called this way, it uses the default address 0x40
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
// you can also call it with a different address you want
//Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x41);
// you can also call it with a different address and I2C interface
//Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x40, Wire);
 
//根据您的伺服品牌,最小和最大脉冲宽度可能会有所不同 调整它
#define SERVOMIN  150 // This is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX  600 // This is the 'maximum' pulse length count (out of 4096)
 
#define SERVO_FREQ 50 // Analog servos run at ~50 Hz updates
 
// our servo # counter
uint8_t servonum = 0;
 
void setup() {
  Serial.begin(9600);
  Serial.println("8 channel Servo test!");
 
  pwm.begin();
//理论上内部振荡器是25MHz,但实际上不是
//非常精确。你可以调整这个数字直到
//你得到了你期望的频率!
  pwm.setOscillatorFrequency(27000000);  // The int.osc. is closer to 27MHz 
  pwm.setPWMFreq(SERVO_FREQ);  // Analog servos run at ~50 Hz updates
 
  delay(10);
}
 
void loop() {
 
  Serial.println(servonum);
  for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen++) {
    pwm.setPWM(servonum, 0, pulselen);
  }
 
  delay(500);
  for (uint16_t pulselen = SERVOMAX; pulselen > SERVOMIN; pulselen--) {
    pwm.setPWM(servonum, 0, pulselen);
  }
 
  delay(500);
 
  servonum++;
  if (servonum > 3) servonum = 0; // Testing the first 8 servo channels
}

  

 

2 串口接收测试

 

//--------------------舵机初始化开始-----------------
 
  
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
  
// called this way, it uses the default address 0x40
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
 
//根据您的伺服品牌,最小和最大脉冲宽度可能会有所不同 调整它
 
//底部舵机-0号口-水平旋转
#define SERVOMIN1  150 //150 // 对应0度
#define SERVOMAX1  600 //150  // 对应180度
 
//底部舵机-1号口-俯仰旋转
#define SERVOMIN2  150//150 // 对应0度
#define SERVOMAX2  600//600 // 对应180度
 
 
 
#define SERVO_FREQ 50 // Analog servos run at ~50 Hz updates
  
int curent_d1=90;
int curent_d2=90;
 
void servo_int()
 { 
   pwm.begin();
  //理论上内部振荡器是25MHz,但实际上不是非常精确。你可以调整这个数字直到
  //你得到了你期望的频率!
  pwm.setOscillatorFrequency(27000000);  // The int.osc. is closer to 27MHz
  pwm.setPWMFreq(SERVO_FREQ);  // Analog servos run at ~50 Hz updates
    
  pwm.setPWM(0, 0, int((SERVOMAX1+SERVOMIN1)/2));// 初始化90度
  delay(50);
  pwm.setPWM(1, 0, int((SERVOMAX2+SERVOMIN2)/2));//初始化90度
  delay(50);
 
          
 }
 
//控制引脚号servonum的舵机
// 0-180   dushu/180*(SERVOMAX-SERVOMIN)
//pwm.setPWM(servonum, 0, pulselen);
 
//--------------------舵机初始化结束-----------------
 
String comdata = "";
  
/*
分割字符串-获取数据类型+数据
数据格式:  名字-数据(混合数据);(分号结尾)
普通灯 开 NomLED-on;  关 NomLED-off;
1个舵机   开 DuoJi-90;(数据范围0-180) 
控制个舵机
模式1 直接过去 开 DuoJiMore-90-90;(数据范围0-180) 
模式2 每一度循环过去 DuoJifor-90-90;
 
*/
 
int speeed=20;
void Fenge(String str){
  
   int index = str.indexOf('-');
   String sensor_class=str.substring(0, index);
   Serial.println(sensor_class);
   String sensor_data=str.substring(index + 1, str.length());
   Serial.println(sensor_data);
  
  // DuoJiMore-90-90-  DuoJiMore-0-0-
 if(sensor_class=="DuoJiMore"){
      
       if (sensor_data){
  
         int nindex = sensor_data.indexOf('-');
         String data1=sensor_data.substring(0, nindex);
         sensor_data=sensor_data.substring(nindex + 1, sensor_data.length());
  
         nindex = sensor_data.indexOf('-');
         String data2=sensor_data.substring(0, nindex);
  
         //String data3=sensor_data.substring(nindex + 1, sensor_data.length());
  
         //Serial.println(data1.toInt());
         //Serial.println(data2.toInt());
         //Serial.println(data3.toInt());
          
         int s1=int(float(data1.toInt())/180.0*float(SERVOMAX1-SERVOMIN1))+SERVOMIN1;
         int s2=int(float(data2.toInt())/180.0*float(SERVOMAX2-SERVOMIN2))+SERVOMIN2;
         //int s3=int(data3.toInt()/180*(SERVOMAX-SERVOMIN));
          
         Serial.println(s1);
         Serial.println(s2);
          
         pwm.setPWM(0, 0, s1);
         delay(50);
         pwm.setPWM(1, 0, s2);
         delay(50);
         
  
        
      }
    }
   
}
  
void setup() {
    Serial.begin(9600);
    while(Serial.read()>= 0){} //clear serialbuffer
   
    servo_int();//舵级初始化
    
}
  
void loop() {
   
   
   if(Serial.available()>0){
      //delay(1);
     
      comdata = Serial.readStringUntil(';');
      //Serial.println(comdata);
      Fenge(comdata);
    }
     
    comdata = "";
     
}

  

3 双舵机 液晶屏 称重机

 

 

 

 

 

//--------------------舵机初始化开始-----------------
#include <Wire.h>
  
#include <Arduino.h>
#include <U8g2lib.h>   



  
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ PB8, /* data=*/ PB9, /* reset=*/ U8X8_PIN_NONE);  

int i=0;

void u8g2_sendStrint(int x,int y,String &msg){
   
    int c_length=msg.length();

    
    if(c_length==0)c_length=20;
    char send_char[c_length];
     
    //char send_char[20]="0";
    strcpy(send_char, msg.c_str());
     
    u8g2.drawStr(x,y,send_char);  // 绘制字符串
   
   
  }


// 重力
#include "HX711.h"
 
 
// HX711 circuit wiring
const int LOADCELL_DOUT_PIN = PB1;
const int LOADCELL_SCK_PIN = PB10;
 
 
HX711 scale;


  
#include <Adafruit_PWMServoDriver.h>
   
// called this way, it uses the default address 0x40
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
  
//根据您的伺服品牌,最小和最大脉冲宽度可能会有所不同 调整它
  
//底部舵机-0号口-水平旋转
#define SERVOMIN1  100 //150 // 对应0度
#define SERVOMAX1  500 //150  // 对应180度
  
//底部舵机-1号口-俯仰旋转
#define SERVOMIN2  150//150 // 对应0度
#define SERVOMAX2  600//600 // 对应180度
  
  
  
#define SERVO_FREQ 50 // Analog servos run at ~50 Hz updates
   
int curent_d1=90;
int curent_d2=90;
  
void servo_int()
 {
   pwm.begin();
  //理论上内部振荡器是25MHz,但实际上不是非常精确。你可以调整这个数字直到
  //你得到了你期望的频率!
  pwm.setOscillatorFrequency(27000000);  // The int.osc. is closer to 27MHz
  pwm.setPWMFreq(SERVO_FREQ);  // Analog servos run at ~50 Hz updates
     
  pwm.setPWM(0, 0, int((SERVOMAX1+SERVOMIN1)/2));// 初始化90度
  delay(50);
  pwm.setPWM(1, 0, int((SERVOMAX2+SERVOMIN2)/2));//初始化90度
  delay(50);
  
           
 }
  
//控制引脚号servonum的舵机
// 0-180   dushu/180*(SERVOMAX-SERVOMIN)
//pwm.setPWM(servonum, 0, pulselen);
  
//--------------------舵机初始化结束-----------------
  
String comdata = "";
   

  
int speeed=20;
void Fenge(String str){
   
   int index = str.indexOf('-');
   String sensor_class=str.substring(0, index);
  // Serial.println(sensor_class);
   String sensor_data=str.substring(index + 1, str.length());
  // Serial.println(sensor_data);
   
  // Fenge DuoJiMore-90-90-;  DuoJiMore-0-0-;
 if(sensor_class=="DuoJiMore"){
       
       if (sensor_data){
   
         int nindex = sensor_data.indexOf('-');
         String data1=sensor_data.substring(0, nindex);
         sensor_data=sensor_data.substring(nindex + 1, sensor_data.length());
   
         nindex = sensor_data.indexOf('-');
         String data2=sensor_data.substring(0, nindex);
   
         //String data3=sensor_data.substring(nindex + 1, sensor_data.length());
   
         //Serial.println(data1.toInt());
         //Serial.println(data2.toInt());
         //Serial.println(data3.toInt());
           
         int s1=int(float(data1.toInt())/180.0*float(SERVOMAX1-SERVOMIN1))+SERVOMIN1;
         int s2=int(float(data2.toInt())/180.0*float(SERVOMAX2-SERVOMIN2))+SERVOMIN2;
         //int s3=int(data3.toInt()/180*(SERVOMAX-SERVOMIN));
           
         //Serial.println(s1);
        // Serial.println(s2);
           
         pwm.setPWM(0, 0, s1);
         delay(50);
         pwm.setPWM(1, 0, s2);
         delay(50);
          
   
         
      }
    }
    
}





  
String msg="11";


void setup() {
    Serial.begin(9600);
    while(Serial.read()>= 0){} //clear serialbuffer
    
    servo_int();//舵级初始化

    u8g2.begin();// 屏幕初始化  



    scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
    scale.set_scale(2280.f);                      // this value is obtained by calibrating the scale with known weights; see the README for details
    scale.tare();                     // reset the scale to 0
}


int weight=0;
String weight_s="000";
String class_="000";

int dgree_zuoyou=0;
String dgree_zuoyou_="000";

void loop() {
    

  
   if(Serial.available()>0){
      //delay(1);
      
      comdata = Serial.readStringUntil(';');
      //Serial.println(comdata);

      //comdata="DuoJiMore-"+String(i)+"-"+String(i)+"-;";
      Fenge(comdata);
  
      
    }

  weight=int(scale.get_units(10));
 
  if(weight<2)
  {
    weight_s=String(weight);
    class_="0";
    dgree_zuoyou=0;
    dgree_zuoyou_=String(dgree_zuoyou);
  }
  else if(weight<10 && weight>2 ){// 酒精
    
    weight_s=String(weight);
    class_="1";
    dgree_zuoyou=0;
    dgree_zuoyou_=String(dgree_zuoyou);
  }
  else if(weight<30 && weight>=10)// 可乐
  {
  
    class_="2";
    weight_s=String(weight);
    dgree_zuoyou=90;
    dgree_zuoyou_=String(dgree_zuoyou);
    
    }
  else if( weight>=30)// 玻璃杯满
  {
       class_="3";
       weight_s=String(weight);
       dgree_zuoyou=180;
       dgree_zuoyou_=String(dgree_zuoyou);
    
    }


    



    Serial.print("分类结果:\t");
    Serial.print(class_);
    Serial.print("\t重量结果:\t");
    Serial.print(weight_s);
    Serial.print("\t分类角度:\t");
    Serial.println(dgree_zuoyou_);
 
  

      
   
    i=i+1;
    msg="time:          "+String(i);
    if(i>100)i=0;
    u8g2.clearBuffer();          // 清除oled缓存
    u8g2.setFont(u8g2_font_ncenB08_tr); // 设置字体
    
    u8g2.drawStr(0,10,"weight: ");  // 绘制字符串
    u8g2_sendStrint(60,10,weight_s);  // 绘制字符串


    u8g2.drawStr(0,25,"class:");  // 绘制字符串
    u8g2_sendStrint(60,25,class_);  // 绘制字符串

    u8g2.drawStr(0,35,"dgree:");  // 绘制字符串 
    u8g2_sendStrint(60,35,dgree_zuoyou_);  // 绘制字符串

    u8g2_sendStrint(0,45,msg);  // 绘制字符串
    
    u8g2.sendBuffer();          // 显示
   

   if(weight<2)
  {
     Serial.println("没有货物,复位,分类舵机0度,倾倒舵机90度");
    comdata="DuoJiMore-"+String(0)+"-90-";  
    Fenge(comdata);
    delay(2000); 
  }
  else{      

    Serial.print("步骤1-分类舵机-分类-旋转到");Serial.println(dgree_zuoyou_); 
    comdata="DuoJiMore-"+String(dgree_zuoyou)+"-90-";  
    Fenge(comdata);
    delay(2000);  

    Serial.println("步骤2-倾倒舵机-倾倒-旋转到0度");
    comdata="DuoJiMore-"+String(dgree_zuoyou)+"-0-";  
    Fenge(comdata);
    delay(2000); 

    Serial.println("步骤3-倾倒舵机-回平-旋转到90度");
    comdata="DuoJiMore-"+String(dgree_zuoyou)+"-90-";  
    Fenge(comdata);
    delay(2000);   
   }
}

  

posted on 2022-04-18 03:03  MKT-porter  阅读(192)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3