`

树莓派和步进电机的故事

阅读更多

程序员从来不缺少对新事物的好奇心和动手探索未知世界的勇气。

从听说树莓派到因好奇购买Model B已经有两年多,最近重新找出来是想实现一台简易的电火花机(电极控制模块),做电火花机是为了给高速钢打孔。

 

电火花机长什么样在网上可以找得到,就是取断丝锥用的型号;

电极控制模块设计思路大致如下:

 

初始时步进电机顺时针转动,电极逐渐靠近工件,达到临界值后开始放电产生电火花;此时工件和电极之间电流很小;

 

当电极和工件之间距离为零时,发生短路,此时电流会达到一个设定的极限值,传感器检测到之后将信号反馈给树莓派,然后控制步进电机逆时针转动,电极远离工件。

 

当电流小于某一临界值后,步进电机正转,如此往复......

 

步进电机和驱动版从网上购买,进电机控制代码如下,用C++编写,前期为了测试,加入了按键控制电机转动方向的逻辑。

 

#include "wiringPi.h"
#include <stdio.h>
#include <stdlib.h>

#include <signal.h>
#include <sys/time.h>

#include <time.h>

#define CLOCKWISE 1
#define COUNTER_CLOCKWISE 2

int flag = 1;

int btn_direction = 1;

int direction = 1;
int pin[] = {26, 27, 28, 29};

void rotate(int* pins, int direction);
void btnInterrupt();
int start_timer();
int main()
{
	if(wiringPiSetup() != -1)  //初始化wiringPi库
	{
		for(int pi = 0;pi < 4; pi++){
			pinMode(pin[pi], OUTPUT);
		}
		printf("test interrput\n");  //打印提示信息
		pinMode(btn_direction, INPUT); //引脚0为输入模式
		pullUpDnControl(btn_direction, PUD_UP);  //设置0号引脚上拉
	}else{
		printf("can't init wiringPi\n");  //初始化失败时,打印出提示信息,并且推出
		return -1;
	}


	//注册中断程序
	if(wiringPiISR(btn_direction, INT_EDGE_FALLING, &btnInterrupt) < 0)  //设置引脚下降沿触发
	{
		printf("unable ISR\n");
	}
        start_timer();
	while(1){
		if(direction == 1){
			rotate(pin, CLOCKWISE);
		}else{
			rotate(pin, COUNTER_CLOCKWISE);
		}
	}
	return 0;
}
//按键服务函数
void btnInterrupt()
{
	flag = 0;
}

void rotate(int* pins, int direction) {
	for (int i = 0; i < 4; i++) {
		if (CLOCKWISE == direction) {
			for (int j = 0; j < 4; j++) {
				if (j == i) {
					digitalWrite(pins[3 - j], 1); // output a high level 
				} else {
					digitalWrite(pins[3 - j], 0); // output a low level 
				}
			}
		} else if (COUNTER_CLOCKWISE == direction) {
			for (int j = 0; j < 4; j++) {
				if (j == i) {
					digitalWrite(pins[j], 1); // output a high level 
				} else {
					digitalWrite(pins[j], 0); // output a low level 
				}
			}
		}
		delay(2);
	}
}

void signalHandler(int signo)
{
    switch (signo){
        case SIGALRM:
            
            int kk = digitalRead(btn_direction);
            if(kk == 1 && flag == 0){
                if(direction == 1){//值被修改并且按键已经抬起
                    direction = 2;
                }else{
                    direction = 1;
                }
                flag = 1;
            }
            printf("%d\n", kk);
            break;
   }
}
//定时轮训变量状态,以确认步进电机方向
int start_timer()
{
    signal(SIGALRM, signalHandler);

    struct itimerval new_value, old_value;
    new_value.it_value.tv_sec = 0;
    new_value.it_value.tv_usec = 1;
    new_value.it_interval.tv_sec = 0;
    new_value.it_interval.tv_usec = 100000;
    setitimer(ITIMER_REAL, &new_value, &old_value);

    return 0;
}

 以上有一部分是为了测试时,物理按键消除抖动的,实际打孔时信号由电流传感器产生,不存在抖动问题。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics