Hello,
I am a newbie. I am trying to create a pneumatic fatigue tester for soft materials. I have an air-driven pneumatic cylinder connected to a solenoid (via a 5V relay switch). As the pneumatic cylinder compresses the sample, I want to measure force using a force-sensing resistor (FSR) and I want to also measure the displacement of the compression using a Time of Fight VL53L0X laser sensor. I send all data through the serial port to a python program that saves the data. My goal is to have different frequencies of loading with the fastest at a delay of 0.1 s. I'm using baud rate of 115200.
Most everything is working perfectly in pieces, but when I have everything (5V relay switch going on and off, FSR collecting data and ToF sensor reading data) my code runs slow (takes about 1 second to advance to the next step)
When I comment out the ToF reading, it goes back to running fast (a delay about .1 s).
My thought is that is something to do with sending information from ToF back to the serial port but I have not able to find others with this problem. Without the ToF sensor, the FSR and relay switch works perfectly. I can control the delay from my python program and data is saved to a file just fine (I don't think there is an issue sending and writing data). In fact, at this point, I am not even sending ToF data back to the computer. It should just read and not do anything with the reading.
Below are details including the wiring diagram, my Arduino code, and my python file. I have also included a picture of my setup.
Any suggestions about why the slow down might be happening would be very helpful. Thank you.
Wiring diagram:
Arduino Code:
#include <Wire.h>
#include <VL53L0X.h>
VL53L0X sensor;
byte newServoPos = 0;
// Define FSR pin:
#define fsrpin A0
//Define variable to store sensor readings:
float fsrreading; //Variable to store FSR value
uint16_t dispreading;
// constants won't change
const int RELAY_PIN = 8; // the Arduino pin, which connects to the IN pin of relay
const byte numLEDs = 2;
byte ledPin[numLEDs] = {12, 13};
unsigned long LEDinterval[numLEDs] = {200, 400};
unsigned long prevLEDmillis[numLEDs] = {0, 0};
const byte buffSize = 40;
char inputBuffer[buffSize];
const char startMarker = '<';
const char endMarker = '>';
byte bytesRecvd = 0;
boolean readInProgress = false;
boolean newDataFromPC = false;
char messageFromPC[buffSize] = {0};
long newFlashInterval = 0;
float servoFraction = 0.0; // fraction of servo range to move
unsigned long curMillis;
unsigned long prevReplyToPCmillis = 0;
unsigned long replyToPCinterval = 100;
//=============
void setup() {
Serial.begin(115200);
Wire.begin();
sensor.setTimeout(500);
if (!sensor.init())
{
Serial.println("Failed to detect and initialize sensor!");
while (1) {}
}
// initialize digital pin 9 as an output.
pinMode(RELAY_PIN, OUTPUT);
// flash LEDs so we know we are alive
for (byte n = 0; n < numLEDs; n++) {
pinMode(ledPin[n], OUTPUT);
digitalWrite(ledPin[n], HIGH);
}
delay(500); // delay() is OK in setup as it only happens once
for (byte n = 0; n < numLEDs; n++) {
digitalWrite(ledPin[n], LOW);
}
// initialize the servo
//myServo.attach(servoPin);
//moveServo();
// Start continuous back-to-back mode (take readings as
// fast as possible). To use continuous timed mode
// instead, provide a desired inter-measurement period in
// ms (e.g. sensor.startContinuous(100)).
//sensor.startContinuous();
//sensor.setMeasurementTimingBudget(20000);
// tell the PC we are ready
Serial.println("<Arduino is ready>");
}
//=============
void loop() {
curMillis = millis();
getDataFromPC();
//updateFlashInterval();
updateSelSwitch();
//updateServoPos();
// Read the FSR pin and store the output as fsrreading:
fsrreading = analogRead(fsrpin);
dispreading = sensor.readRangeSingleMillimeters();
//dispreading = sensor.readRangeContinuousMillimeters();
replyToPC();
//Serial.println("<Msg LED1 NewFlash 1 SrvFrac 16.0000 SrvPos 0 Time 6881>");
//flashLEDs();
//moveServo();
}
//=============
void getDataFromPC() {
// receive data from PC and save it into inputBuffer
if(Serial.available() > 0) {
char x = Serial.read();
// the order of these IF clauses is significant
if (x == endMarker) {
readInProgress = false;
newDataFromPC = true;
inputBuffer[bytesRecvd] = 0;
parseData();
}
if(readInProgress) {
inputBuffer[bytesRecvd] = x;
bytesRecvd ++;
if (bytesRecvd == buffSize) {
bytesRecvd = buffSize - 1;
}
}
if (x == startMarker) {
bytesRecvd = 0;
readInProgress = true;
}
}
}
//=============
void parseData() {
// split the data into its parts
char * strtokIndx; // this is used by strtok() as an index
strtokIndx = strtok(inputBuffer,","); // get the first part - the string
strcpy(messageFromPC, strtokIndx); // copy it to messageFromPC
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
newFlashInterval = atol(strtokIndx); // convert this part to an integer, using atol, not atoi
strtokIndx = strtok(NULL, ",");
//servoFraction = (float) atof(strtokIndx); // convert this part to a float
fsrreading = (float) atof(strtokIndx); // convert this part to a float
//Serial.print(servoFraction);
}
//=============
void replyToPC() {
if (newDataFromPC) {
newDataFromPC = false;
Serial.print("<Msg ");
Serial.print(messageFromPC);
Serial.print(" NewFlash ");
Serial.print(newFlashInterval);
Serial.print(" SrvFrac ");
//Serial.print(servoFraction,4);
Serial.print(fsrreading,4);
Serial.print(" SrvPos ");
Serial.print(newServoPos);
Serial.print(" Time ");
//Serial.print(curMillis >> 9); // divide by 512 is approx = half-seconds
Serial.print(curMillis); // divide by 512 is approx = half-seconds
Serial.println(">");
}
}
//============
void updateFlashInterval() {
// this illustrates using different inputs to call different functions
if (strcmp(messageFromPC, "LED1") == 0) {
updateLED1();
}
if (strcmp(messageFromPC, "LED2") == 0) {
updateLED2();
}
}
void updateSelSwitch(){
if(newFlashInterval == 1 ){
digitalWrite(RELAY_PIN, HIGH);
}
if(newFlashInterval == 0 ){
digitalWrite(RELAY_PIN, LOW);
}
}
//=============
void updateLED1() {
if (newFlashInterval > 100) {
LEDinterval[0] = newFlashInterval;
}
}
//=============
void updateLED2() {
if (newFlashInterval > 100) {
LEDinterval[1] = newFlashInterval;
}
}
//=============
void flashLEDs() {
for (byte n = 0; n < numLEDs; n++) {
if (curMillis - prevLEDmillis[n] >= LEDinterval[n]) {
prevLEDmillis[n] += LEDinterval[n];
digitalWrite( ledPin[n], ! digitalRead( ledPin[n]) );
}
}
}
Python Code:
When I post this, I get an error that the message is too long. So I will post a reply with the code.
Picture of setup:
ArduinoPC2.ino (5.18 KB)
python-code.pdf (40 KB)