So I figured out the problem, but first, here is my code:
Code:
#include <ros.h>
#include <std_msgs/Float32.h>
#include <sensor_msgs/Imu.h>
#include "QuadEncoder.h"
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
#include <utility/imumaths.h>
#define PI 3.1415926535897932384626433832795
/**********Function Prototypes**************/
void posCb(const std_msgs::Float32& msg);
void PID();
void getimu();
/***********************************/
/************VARIABLES********************/
IntervalTimer steering1Control;
IntervalTimer imuUpdate;
QuadEncoder steering1(1,2,3,0);
ros::NodeHandle nh;
std_msgs::Float32 stepperAngle;
sensor_msgs::Imu imu_dat;
ros::Publisher jointstate("steeringPos", &stepperAngle);
ros::Publisher imupub("/imu/data", &imu_dat);
ros::Subscriber<std_msgs::Float32> angle("SteeringAngle", &posCb);
volatile short int sp = 0;
volatile short int error = 0;
Adafruit_BNO055 bno = Adafruit_BNO055(55,0x28);
volatile sensors_event_t orientationData , angVelocityData , linearAccelData;
volatile sensors_event_t event;
/************************************************/
void setup()
{
if(!bno.begin())
{
//if not detected, infinite loop
while(1);
}
steering1.setInitConfig();
//steering1.EncConfig.INDEXTriggerMode = RISING_EDGE;
steering1.init();
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
//nh.getHardware()->setBaud(256000);
nh.initNode();
nh.advertise(jointstate); //publisher for current angle
nh.advertise(imupub);
nh.subscribe(angle); //angle of steering command
bno.setExtCrystalUse(true);
imu_dat.header.frame_id = "imu";
steering1Control.begin(PID,5000);//200 hz timer interrupt loop
//imuUpdate.begin(getimu,10000);//100hz timer interrupt
}
void loop()
{
stepperAngle.data = steering1.read();
noInterrupts();
imu_dat.orientation.x = event.orientation.x;
imu_dat.orientation.y = event.orientation.y;
imu_dat.orientation.z = event.orientation.z;
interrupts();
jointstate.publish(&stepperAngle);//current positions
imu_dat.header.stamp = nh.now();
imupub.publish(&imu_dat);
nh.spinOnce();
delay(4);
}
void posCb(const std_msgs::Float32& msg){//callback for 250hz subscriber
noInterrupts();
sp = map(msg.data,-PI/2,PI/2,-1000,1000);
interrupts();
}
void PID(){//ISR for PID loop for position of stepper motor
/*
if(abs(steering1.read())>1100){
analogWrite(11, 0);
return;
}*/
error=sp-steering1.read();
if(error>=0){
digitalWrite(10, HIGH);
}else{
digitalWrite(10, LOW);
error=error*(-1);
}
if(error*100>30000){
analogWriteFrequency(11, 30000);
}else{
analogWriteFrequency(11, error*100);
}
analogWrite(11, 200);
}
void getimu(){
bno.getEvent(&event);
bno.getEvent(&angVelocityData, Adafruit_BNO055::VECTOR_GYROSCOPE);
bno.getEvent(&linearAccelData, Adafruit_BNO055::VECTOR_LINEARACCEL);
}
The issue is the stepper motor encoder signals I am getting. I tried this same code with another motor and it doesnt miss ticks. The stepper motor i am using provides differential encoder signals for the a and b channels. I have hooked up 2 wires from the a+ and b+ channel of the stepper motor driver (its a closed loop driver) to the teensys pins as well as ground. I am not sure why this wont produce reliable data. I tried seperating the wires even more but the results are the same. Is there a way to hook up the differential signals for data? or a converter that is to be used?