PySerial - How to send numbers larger than 256?

That is correct, your library works with ‘long’ values that represent a number of steps.

Hi everybody,

I´ve checked the codes now so many times and this is realy hard because I´m a absolutely unknown about programming. I´ve never learned such stuff (sadly). First of all I realized that my beginning code (the first one I posted) did not work. I think I made some hardware mistake, because I used the same breadbord for servomotors and maybe there was some voltage on the stepper pins…I don´t know.

With the help I got on this thread, I put together different pieces and now I made a very little step forward, but it´s curious anyway :slight_smile:

Let me explain:

The setup for the big easy driver is 200 steps per revolution an I animated a cube in blender the following way. Frame one is 200 degrees, frame two is 600 degrees and frame three is 1000 degrees (rotation on the y-axis).

The blender code:

import bpy
import math
import struct
from math import degrees
import serial
ser = serial.Serial('COM5',115200,timeout=1)
def my_handler(scene):
    eulx = bpy.data.objects['Cube'].rotation_euler
    x = degrees(eulx.y)
    xa = int(x)
    xb = xa.to_bytes(2,'big',signed=True)
    ser.write(xb)
bpy.app.handlers.frame_change_post.append(my_handler)

The arduino code:

#include <AccelStepper.h>
int motorSpeed = 30; //maximum steps per second (about 3rps / at 16 microsteps
int motorAccel = 20000; //steps/second/second to accelerate
int motorDirPin = 9; //digital pin 2
int motorStepPin = 8; //digital pin 3
int num;
//set up the accelStepper intance
//the "1" tells it we are using a driver
AccelStepper stepper(1, motorStepPin, motorDirPin);
void setup(){
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);
  digitalWrite(7, LOW);
  stepper.setMaxSpeed(motorSpeed);
  stepper.setSpeed(motorSpeed);
  stepper.setAcceleration(motorAccel);
  Serial.begin(115200);
  stepper.moveTo(0); //move 32000 steps (should be 10 rev)
}
int numbuffer = 0;
void loop()
{
  int bytesToRead = 2;
  while(Serial.available() > 0 && bytesToRead > 0) {
    int serialByte = Serial.read();
    numbuffer += serialByte << ((bytesToRead - 1) * 8);
    bytesToRead = bytesToRead - 1;
  }
  stepper.runToNewPosition(numbuffer);
  delay(5000);
}


When I now jump to frame 1, the stepper turns one revolution, when I jump on frame two it makes 3 revolutions and yes, on frame 3 it makes 5 revolutions.

But when I change just a little of that code, it won´t work anymore :frowning:

For example:

#include <AccelStepper.h>
int motorSpeed = 30; //maximum steps per second (about 3rps / at 16 microsteps
int motorAccel = 20000; //steps/second/second to accelerate
int motorDirPin = 9; //digital pin 2
int motorStepPin = 8; //digital pin 3
int num;
//set up the accelStepper intance
//the "1" tells it we are using a driver
AccelStepper stepper(1, motorStepPin, motorDirPin);
void setup(){
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);
  digitalWrite(7, LOW);
  stepper.setMaxSpeed(motorSpeed);
  stepper.setSpeed(motorSpeed);
  stepper.setAcceleration(motorAccel);
  Serial.begin(115200);
  stepper.moveTo(0); //move 32000 steps (should be 10 rev)
}
int numbuffer = 0;
void loop()
{
  int bytesToRead = 2;
  while(Serial.available() > 0 && bytesToRead > 0) {
    int serialByte = Serial.read();
    numbuffer += serialByte << ((bytesToRead - 1) * 8);
    bytesToRead = bytesToRead - 1;
  }
  numbuffer = num
  stepper.runToNewPosition(num);
  delay(5000);
}

Everything stands still. I do so, because I´ll need some math going on after the buffer. Frame 2 = Frame 2 - Frame 1 and so on… But everything I add makes the code fail.

Can anyone pleas tell me why this can happen?

Thanx
Mat

You have a few things going on with your code.

  1. Are you sure that the sketch is even compiling and uploading? There was a missing ‘;’
  2. Your changes make you lose the value you have read from the serial port. Check my comments.
  3. Your delay(5000) is going to freeze your sketch for 5 seconds. This might cause the stepper library
    to lockup as well.


int numbuffer = 0;
void loop(){
  int bytesToRead = 2;
  numbuffer = 0;                   // CHANGE HERE: Ensure that numbuffer is zero'ed out
  while(Serial.available() > 0 && bytesToRead > 0) {
    int serialByte = Serial.read();
    numbuffer += serialByte << ((bytesToRead - 1) * 8);
    bytesToRead = bytesToRead - 1;
  }
  numbuffer = num;        // CHANGE HERE: Added a ';' at the end of the line.  This is wiping out the value you've read into 'numbuffer'  
stepper.runToNewPosition(num);   // You should remove the assignment 'numbuffer = num' and just pass 'numbuffer' here.  delay(5000);}

Yes, you are right.

I took this large delay because I also test it out on the serial monitor as you mentioned. And so it is much easier to see whats going on.

Is it possible to do the math in Blender´s frame_change? So that Blender does the work and not the arduino? I´ve tried to figure that out with no results. Blender looses the oldstep on the frame_change.

Thank you
Mat

I would recommend sending an absolute position from Blender to the Arduino and letting the Arduino figure out how many steps it needs to move and in which direction to get to that position. The motor cannot change position instantly so the Arduino is in a better place to accept an absolute position, figure out the current position, and adjust by the delta.

If you want to do the work in Blender then you will need a way for the Arduino to report back the current position of the stepper motor.

Ok, thanks for the clear statement and good explanation (so noob like me can understand it).

Today I´ve tried all the other functions of accelstepper in combination with the blender code (move, moveTo, runToPosition…). NOTHING works, except the method runToNewPosition. And this does not work correctly.

Let me explain:

If I do the coding only on the arduino like this:

#include <AccelStepper.h>
int motorSpeed = 300; //maximum steps per second (about 3rps / at 16 microsteps
int motorAccel = 20000; //steps/second/second to accelerate
int motorDirPin = 9; //digital pin 2
int motorStepPin = 8; //digital pin 3
int num;
//set up the accelStepper intance
//the "1" tells it we are using a driver
AccelStepper stepper(1, motorStepPin, motorDirPin);
void setup(){
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);
  digitalWrite(7, LOW);
  stepper.setMaxSpeed(motorSpeed);
  stepper.setSpeed(motorSpeed);
  stepper.setAcceleration(motorAccel);
  Serial.begin(115200);
  stepper.moveTo(0); //move 32000 steps (should be 10 rev)
}
int num1 = 200;
int num2 = 600;
int num3 = 1000;
int num4 = 800;
int num5 = 1200;
int num6 = 1600;
void loop()
{
  stepper.runToNewPosition(num1);
  delay(500);
  stepper.runToNewPosition(num2);
  delay(500);
  stepper.runToNewPosition(num3);
  delay(500);
  stepper.runToNewPosition(num4);
  delay(500);
  stepper.runToNewPosition(num5);
  delay(500);
  stepper.runToNewPosition(num6);
  delay(500);
}

Now the runToNewPosition-method works correctly: 1 rev forward, 2 rev forward, 2 rev forward, 1 rev backward, 2 rev forward and 2 rev forward.

If I do this with the code in my post above, it moves: 1 rev forward, 3 rev forward, 5 rev forward, 4 rev forward, 6 rev forward and 8 rev forward. So with python he interprets it as stepps I think.

Which kind of data do I send with my python code? Long, int, float…

How can I send data the accelstepper interprets right and let me use other methods too?

Thank you very much!
Mat