Serial communication with a teensy.

Hi, I’m not sure if this is the correct subforum for this post, so please move it if supposed to be posted in another subforum

I’m trying to build a 3d scanner with the use of a line laser, web camera and a stepper motor. Found the processing code

The stepper motor and laser is to be controlled by the teensy when sending commands via the serial port.

I first tried out sending and decoding strings, but that was a bit too complicated for me. So I went for a binary format instead. My aim is to send one byte, containing the command in two of the bits and the value associated with the command in the other 6. I managed to turn on and off the laser this way. But when I try to make a loop for stepping the stepper motor it fails. For debugging I’m turning on and off the onboard led to indicate steps. The thing is that it wont flash.

At a later stage I will also replace delay() and also add replies from the teensy to processing.

Could you please have a look at my code and help me figure out what I’m doing wrong.

Thanks
//Flog

arduino/teensy code:

//stepper motor pins
const int motorEnablePin = 4;
const int motorStepPin = 1;
const int motorDirPin = 0;

const int ledPin = 13;
const int laserPin = 5;

byte laserOn;
byte ledOn;
byte motorOn;
byte motorStep;
boolean pulse;

byte inByte;
byte inputVal;
byte inputCmd;

int stepsStepped = 0;

void setup(){
  pinMode(motorEnablePin, OUTPUT);
  pinMode(motorStepPin, OUTPUT);
  pinMode(motorDirPin, OUTPUT);
  
  pinMode(ledPin, OUTPUT);
  pinMode(laserPin, OUTPUT);
  
  digitalWrite(motorEnablePin, HIGH);
  Serial.begin(9600);
}

void loop(){
  /*
  Commandformat <command>,<value>
  1 = LaserOn
  2 = motorOn
  3 = motorStep 
  */
  
  if(Serial.available() > 0) {
    inByte = Serial.read();
    inputVal = 0x00111111 & inByte; //mask out value
    inputCmd = inByte >> 6;         //shift to get command
    Serial.write(inputCmd);         //print command for debug
    Serial.write(inputVal);         //print value for debug
  }
   
    //determin command the value represents and execute command
    switch(inputCmd){
      case 1:
        constrain(inputVal, 0, 1);
        laserOn = inputVal;
        digitalWrite(laserPin, inputVal);
        break;
        
      case 2:
        constrain(inputVal, 0, 1);
        motorOn = inputVal; //enables stepper motor driver
        if(motorOn == 1){
          digitalWrite(motorEnablePin, LOW);
        }
        if(motorOn == 0){
          digitalWrite(motorEnablePin, HIGH);
        }
        break;
        
      case 3:
        motorStep = inputVal; //Numbers of steps to steps
        break;
     }
     
     //delay to be changed out at later stage
     if(motorOn == 1 && motorStep < stepsStepped){
       digitalWrite(ledPin, HIGH); //blink led for testing, should be motorStepPin later
       delay(50);
       digitalWrite(ledPin, LOW);
       delay(50);
       stepsStepped++;
     }
     if(stepsStepped >= motorStep){
       stepsStepped = 0;
     }
}

Processing code:

import processing.serial.*;

Serial teensy;

int indata;

void setup(){
  teensy = new Serial(this, Serial.list()[5], 9600);
}

void draw(){
  
  //delay to be changed out at later stage
  
  motorOn(1); //enable stepper motor driver
  delay(1000);
  step(20);   //tell teensy to step x steps
  delay(1000);
  motorOn(0); //disable stepper motor driver
  delay(1000);
  

  laser(1);    //turn on laser
  delay(1000);
  laser(0);    //turn off laser
  delay(1000);
}

/*
All command functions send 1byte where(counting from right)
6 first are the value and the 2 last are the command.
*/

void laser(int val){
  int cmd = 1;
  cmd = cmd << 6;
  int output = cmd + val;
  teensy.write(output);
  println(binary(teensy.read()));
}

void motorOn(int val){
  int cmd = 2;
  cmd = cmd << 6;
  int output = cmd + val;
  teensy.write(output);
  println(binary(teensy.read()));
}

void step(int val){
  int cmd = 3;
  cmd = cmd << 6;
  int output = cmd + val;
  teensy.write(output);
  println(binary(teensy.read()));
}

With serial it is actually easier to transmit and receive strings than bytes. I’m not sure how you are going to split each byte into 2 and 6 bits respectively. Below is an example of just how easy the whole thing is.

int serial_read = Serial.read();
Serial.write("OK");

// put if...else if branch for handling serial_read

Sending the byte and extract the bits is working fine. It's is probably the loop to step the motor that wont work. But I don't understand why.

With your suggestion for sending strings instead. How would you parse a string containing command and value?

      case 3:
        motorStep = inputVal; //Numbers of steps to steps
        break;
     }
     
     //delay to be changed out at later stage
     if(motorOn == 1 && motorStep < stepsStepped){
       digitalWrite(ledPin, HIGH); //blink led for testing, should be motorStepPin later
       delay(50);
       digitalWrite(ledPin, LOW);
       delay(50);
       stepsStepped++;
     }
     if(stepsStepped >= motorStep){
       stepsStepped = 0;
     }

Your logic around this code is not good.
motorStep < stepsStepped will never happen if stepsStepped starts at zero. There are other errors also but…

If your sending commands in a single byte then why bother with such a complex system.
Just have different byte values (you in effect do anyway) for laser on/off, enable on/off and step. Don’t bother encoding the number of steps in the command byte just send a step once command how ever many times it’s needed.

Riva:
Your logic around this code is not good.
motorStep < stepsStepped will never happen if stepsStepped starts at zero. There are other errors also but…

If your sending commands in a single byte then why bother with such a complex system.
Just have different byte values (you in effect do anyway) for laser on/off, enable on/off and step. Don’t bother encoding the number of steps in the command byte just send a step once command how ever many times it’s needed.

Thanks for pointing out the if case issue. But I might go with your suggestion in the end.