// Serial-controlled stepper motor
// Based on:
//
// https://wokwi.com/projects/327823888123691604
// Arduinozyme from https://github.com/WardCunningham/Txtzyme
// stepper code from https://forum.arduino.cc/t/want-to-control-stepper-motor-angle-via-serial/1096201
//
// https://github.com/WardCunningham/Txtzyme/blob/master/Arduinozyme/Arduinozyme.ino
// Note the 32:1 gear ratio on Wokwi's diagram.json
unsigned int x = 0; // general purpose value
long int d = 13; // pin register
const unsigned int bufsize = 128; // 2048 is too large for Arduino Uno
int PUL =4; //define Pulse pin
int DIR =3; //define Direction pin
int ENA =2; //define Enable Pin
int steps_pr = 6400; //steps per revolution ( changable ) --<<<<<<<<<<<<<<<<<<<<< set based on stepper DIP config
int long target_ = 90; // move by degree ( changable ) --<<<<<<<<<<<<<<<<<<<<< test 2 function
int rotation_amt = 0; // rotation number ( changable ) --<<<<<<<<<<<<<<<<<<<<<
uint32_t stepDelay = 500;
//-----------------------------------------------( test 1 functions only) rotation counter only )----------------------------
bool test_done = false; // test code finishes exicution
int step_ = 0; // current step
int rot_ = 0; // current rotation
// ----------------------------------------------( degree specification )--------------------------------------------------
float step_per_degree = 6400/360.0; // the number of steps in a degree
int long cur_step = 0; // the current step (holder) must be intiger
float calculated_step = step_per_degree * target_; // (180*17.7777~8 ) = 3,200.00~
int long rounded_step = abs(round(calculated_step)); // calc rounded
bool test2_done = false;
void doHelp(){
Serial.print(F("0-9: Accumulate digits into a x. p: print number\n"
"d: copy number to d. i:pinmode(d,INPUT), I: pinMode(d,INPUT_PULLUP), s: x=analogRead(d) r: digitalRead(d)\n"
"o: output x digital, O: output x analog\n"
"T: tone(d,x). m: delay(x). {...}: loop k=x times. k: copy k to x \n"
"A: step to angle x, f: step(+x): b: step(-x), D: delayMicros(x) between steps \n"
"try: 10{_k:_kpf1500m} loop down from 10, printing and stepping, and pause between motions.\n"
"or try: 180A 5{45b 1000m 500D 90f 1000m 5000D _boop_}\n"
));
}
void setup() {
//txtEval("10d10T 1000m 2T 1000m 0T 0o\r\n"); // hint for a startup command
pinMode (PUL, OUTPUT); // set out pins
pinMode (DIR, OUTPUT);
pinMode (ENA, OUTPUT);
digitalWrite(ENA,LOW); // disable on start
Serial.begin(9600);
Serial.println("Txtzyme h?diIoOmprTksAbf{}+ ");
}
void loop() {
char buf[bufsize];
txtRead(buf, bufsize); // wait for commands
txtEval(buf);
}
void txtRead (char *p, unsigned int n) {
unsigned int i = 0;
while (i < (n - 1)) {
while (!Serial.available()); // loop while waiting for input
char ch = Serial.read();
if (ch == '\r' || ch == '\n') break;
if (ch >= ' ' && ch <= '~') {
*p++ = ch;
i++;
}
}
*p = 0;
}
void txtEval (char *buf) {
unsigned int k = 0;
char *loop;
char ch;
while ((ch = *buf++)) {
switch (ch) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
x = ch - '0';
while (*buf >= '0' && *buf <= '9') {
x = x * 10 + (*buf++ - '0');
}
break;
case 'p':
Serial.println(x);
break;
case 'd':
d = x;
break;
case 'i':
pinMode(d, INPUT);
case 'I':
pinMode(d, INPUT_PULLUP);
case 'r':
x = digitalRead(d);
break;
case 'o':
pinMode(d, OUTPUT);
digitalWrite(d, x % 2);
break;
case 'O': // write analog
pinMode(d, OUTPUT);
analogWrite(d, x);
break;
// Teensy 3.1 and 3.0 specifc code
#if defined(__MK20DX256__)|| defined(__MK20DX128__)
case 'F': // See https://www.pjrc.com/teensy/td_pulse.html
analogWriteFrequency(d, x);
break;
case 'R': // Teensy3 bits of resolution 2-16 default was 8
analogWriteResolution(x);
break;
#endif
case 'T':
if (x == 0 )
noTone(d);
else
tone(d, x);
break;
case 'm':
delay(x);
break;
case '{':
k = x;
loop = buf;
while ((ch = *buf++) && ch != '}') {
}
case '}':
if (k) {
k--;
buf = loop;
}
break;
case 'k':
x = k;
break;
case '_':
while ((ch = *buf++) && ch != '_') {
Serial.print(ch);
}
Serial.println();
break;
case 's':
x = analogRead(x);
break;
case 'A': // step to Angle `x`
{
int32_t stepsToGo = x * step_per_degree - cur_step;
int8_t inc = stepsToGo > 0 ? 1 : -1;
while (stepsToGo) {
stepsToGo-=inc;
doStep(inc);
}
}
break;
case 'b': // step backward by Angle 'x'
case 'f': // step forward by Angle 'x'
{
int32_t stepsToGo = x * step_per_degree;
while (stepsToGo) {
--stepsToGo;
doStep(ch == 'f' ? 1 : -1);
}
}
break;
case 'D': // set Delay micros between steps
stepDelay = x;
break;
case 'h':
case '?':
doHelp();
}
}
}
int doStep(int8_t direction) {
if (direction > 0) {
digitalWrite(DIR, HIGH);
++cur_step;
} else {
digitalWrite(DIR, LOW);
--cur_step;
}
//digitalWrite(ENA, HIGH);
digitalWrite(PUL, HIGH);
delayMicroseconds(5); // no less than 50 ( under torque issue.. nema 23 works )
digitalWrite(PUL, LOW);
delayMicroseconds(stepDelay);
}