Hi, I am raking my brain on this. I am using an Inland Nano v3 board (a knock off Arduino Nano v3). A 12v bi-directional stepper motor I got at Micro Center (the $13.99 one with 4 wires). A DRV 8825 stepper driver board wired to D2 for the direction pin and D3 for the step pin. And an Inland R.E. sensor (a knock off KY040), wired to D7 for CLK, D8 for DT, and D9 for SW.
The original project calls for a una-directional, 12v stepper motor with a hall sensor built in and only has 3 wires for the motor and 5 for the hall sensor (3 for the sensor plus a power and a ground). The original driver board is the JYDQ 7v3.
I am using code from github provided by the uploader of the project on Thingiverse. I have made modifications for the DRV 8825 as provided for by the afore mentioned github repository. Where I run into problems is getting the reading from the KY040 to fit into the speed control portion of the code that is required for the DRV 8825 to run the motor. I can interrupt the motor and reset it by pressing the button of the encoder. I can start the motor turning by turning the knob of the encoder. However, I want the motor speed to increase when I turn the knob further away from the start position and decrease when I move it back toward the start position. and this is not happening. I know which line will require a reading of the encoder, I just don't quite know how to go about it.
Here is the code I'm working with:
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
//#include <Fonts/FreeMono9pt7b.h>
#include <gfxfont.h>
#include <Arduino.h>
#include "A4988.h"
#include "TimerOne.h"
#define MOTOR_STEPS 200
#define DIR 2
#define STEP 3
A4988 stepper(MOTOR_STEPS, DIR, STEP);
const int GEAR_A = 17; //25
const int GEAR_B = 63; //30
const int SIGPR = 24;
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET 4
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define DBG
#ifdef DBG
#define Serial_begin Serial.begin
#define Serial_println Serial.println
#define Serial_print Serial.print
#else
#define Serial_begin(x)
#define Serial_println(x)
#define Serial_print(x)
#endif
const int PinCLK = 7; // Used for generating interrupts using CLK signal
const int PinDT = 8; // Used for reading DT signal
const int PinSW = 9; // Used for the push button switch
bool bLastCLK = false;
const int PinSig = 4;
void setup() {
Serial_begin(9600);
Serial_println("Woolwinder");
pinMode(PinSig, INPUT);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(LED_BUILTIN, OUTPUT);
pinMode(PinCLK, INPUT);
pinMode(PinDT, INPUT);
pinMode(PinSW, INPUT_PULLUP);
//attachInterrupt (1,isr,CHANGE); // interrupt 1 is always connected to pin 3 on Arduino UNO
bLastCLK = digitalRead(PinCLK);
display.begin(SSD1306_SWITCHCAPVCC, 0x3D); // initialize with the I2C addr 0x3D (for the 128x64)
//display.setFont(&FreeMono9pt7b);
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0, 1);
display.print("Woolwinder");
display.display();
delay(1000);
Timer1.initialize(100); // 10 us = 100 kHz
Timer1.attachInterrupt(stepperAdvance);
Serial_println("init.done");
stepper.begin(150, 1); // This is required in the void setup. Here is where the sensor reading, conversion and output would need to go. as this tells the DRV 8825 how fast, and how much rotation the motor should take. 150 is a set speed, 1= full rotation as I understand the code. correct me if I'm wrong or missing some information.
}
unsigned int cnt = 0;
int iRPM = 0;
unsigned long iStepCount = 0;
/*void isr () { // Interrupt service routine is executed when a HIGH to LOW transition is detected on CLK
bool bCLK=digitalRead(PinCLK);
bool bDT=digitalRead(PinDT);
Serial_print(bCLK);
Serial_print(",");
Serial_print(bDT);
Serial_print("\n");
bool up = bCLK == bDT;
if(up) iRPM-=5; else iRPM+=5;
if(iRPM<0) iRPM=0;
if(iRPM>400) iRPM=400;}*/
void loop() {
handleDisplay();
cnt++;
digitalWrite(LED_BUILTIN, ((cnt / 10) & 1) != 0);
const int iMin = 30;
analogWrite(2, iMin + (long(iRPM) * (255 - iMin) / 1000));
if (iRPM < 1) return;
stepper.rotate(360); // This is required in the void loop to make the motor turn. As I understand the code again correct me if I'm wrong.
#ifdef DBG
//*
unsigned int iNM = millis();
static unsigned int iLastLog = 0;
if (iNM > iLastLog + 500) {
iLastLog = iNM;
const long iRot = (iStepCount * GEAR_A) / (GEAR_B * SIGPR);
//const int iMSTEPS=(long(STEPS_PERREV*32)*GEAR_B)/GEAR_A;
Serial_print(iRPM);
Serial_print(",");
Serial_print(iStepCount);
Serial_print(",");
Serial_print(iRot);
Serial_print("\n");
cnt = 0;
}/**/
#endif
//Serial.println("loop");
}
unsigned long iLastStep = 0;
bool bStepOn = false;
unsigned int iClick = 0;
bool bSig = false;
void stepperAdvance() {
unsigned long iNow = micros();
if (iNow < iLastStep) {
iLastStep = iNow;
}; //overflow
bool bCLK = digitalRead(PinCLK);
if (bLastCLK != bCLK) {
bLastCLK = bCLK;
bool bDT = digitalRead(PinDT);
if (bDT != bCLK) {
iRPM += 20;
if (iRPM > 1000) iRPM = 1000;
} else {
iRPM -= 20;
if (iRPM < 0) iRPM = 0;
}
}
if (!(digitalRead(PinSW))) {
//Serial_print(iClick);
iClick++;
if (iClick > 7000) {
iStepCount = 0;
};
iRPM = 0;
} else {
iClick = 0;
}
bool bS = digitalRead(PinSig);
if (bS != bSig) {
iStepCount++;
bSig = bS;
};
digitalWrite(3, iRPM > 0);
}
void handleDisplay() {
String rpm = String(iRPM);
const long iRot = (iStepCount * GEAR_A) / (GEAR_B * SIGPR);
//iRot=iRevCount;
String cnt = String(iRot);
int iW = (long(iRPM) * 126) / 1000;
display.clearDisplay();
display.writeFastHLine(0, 0, 128, 1);
display.writeFastVLine(0, 0, 16, 1);
display.writeFastHLine(0, 15, 128, 1);
display.writeFastVLine(127, 0, 16, 1);
display.writeFillRect(1, 1, iW, 14, 1);
//display.setTextSize(2);
//display.setTextColor(WHITE);
//display.setCursor(0,1);
//display.print("RPM: ");
//display.println(rpm);
display.setTextSize(4);
display.setCursor(0, 28);
display.println(cnt);
display.display();
}
Any advice is appreciated. Also if this problem has already been solve elsewhere please point it out to me. I just want to wind my yarn.
Preformatted text