Tarnarmour
New member
I'm using a Teensy 4.0 to read some data from a pair of flow sensors. The code I've written here is hanging in the setup function, but not at a specific function. It hangs at whatever the last function to actually execute in the setup function is. IE, if I try to tell the sensors to reset, then read some data off them, it will hang at the last actual function call in that process. If I stick some instructions to set some bits high or low AFTER that, then the pin high or low thing will hang. Whatever is last in the setup function (as long as it actually compiles, if I just set some variables that aren't used anywhere and the compiler catches it then they will not be the last function to be called) hangs.
I'm pretty baffled. I've only got moderate Arduino experience so it could definitely just be a mistake somewhere obvious on my side. In any case I'm looking forward to the explanation for this one!
I'm pretty baffled. I've only got moderate Arduino experience so it could definitely just be a mistake somewhere obvious on my side. In any case I'm looking forward to the explanation for this one!
Code:
#include <Wire.h>
const int FLOW1PWR = 22; // digital IO pin to flow 1 mosfet, low for on, high for off
const int FLOW2PWR = 23; // digital IO pin to flow 2 mosfet, low for on, high for off
const int PRESSUREPIN = 1; // Analog input pin for pressure sensor
const uint8_t addr1 = 0x2E;
const uint8_t addr2 = 0x2E;
const uint8_t commandMeasure[2] = {0x36, 0x08}; // command for the new sensor to start measurements
const uint8_t commandAverage[2] = {0x36, 0x66}; // command for the new sensor to change averaging mode. The following command should be the number of samples to average, with 0 being average until read
const uint8_t commandReset[2] = {0x00, 0x06}; // command to reset the new sensor (0x00 is the address, one byte message?)
const float scaleFactor = 170; // scale factor for new sensor
const float sensorOffset = -24576; // offset for the new sensor. New sensor transmits data as a 2's compliment number
const float VDD = 5.0;
float flow1Topic = 0;
float flow2Topic = 0;
float pressureTopic = 0;
bool verb = false; // true to print data every loop, false to print when queried
void setup()
{
PinSetup();
Wire.begin();
Wire1.begin();
Serial.begin(9600);
while(!Serial){ }
Serial.println("Begin");
delay(5); // see SFM3019 datasheet table 2.4 for reset timing requirements
Serial.print("-1 ");
WireWrite(commandReset,addr1,0); // send reset to sensor 1
Serial.print("-1.1 ");
WireWrite(commandReset,addr2,1); // send reset to sensor 2
delay(3);
Serial.print("-2 ");
WireWrite(commandMeasure,addr1,0); // start measurement command
Serial.print("-2.1 ");
WireWrite(commandMeasure,addr2,1); // start measurement command
Serial.print("-3 ");
FlowOnePwr(false);
FlowTwoPwr(false);
Serial.print("-4 "); // currently this is the last thing it executes, it hangs on the delay function. If I get rid of the delay function it will hang on the FlowTwoPwr() call.
delay(10);
PinSetup();
Serial.print("-5 ");
}
void loop()
{
Serial.println("loop");
pressureTopic = GetPressure();
int flow1state = WireWrite(0, addr1, 0); // check status of sensors by sending empty message and checking for NACK
int flow2state = WireWrite(0, addr2, 1);
if (flow1state == 2 || flow1state == 4)
{
if (flow2state == 2 || flow2state == 4)
{
ResetSensor(3);
}
else
{
ResetSensor(1);
}
}
else if (flow2state == 2 || flow2state == 4)
{
ResetSensor(2);
}
byte data[3] = {0, 0, 0xFF};
Serial.println("check3");
if (flow1state == 0)
{
WireRead(addr1,3,0,data);
if (CrcCheck(data) == 0)
{
int holder = ((data[0] << 8) + data[1]);
holder = -(holder & 32768) + (holder & 32767); // 2's complement from the bytes
flow1Topic = (holder - sensorOffset) / scaleFactor;
}
}
data[0] = 0; // clear data between reading in case read fails
data[1] = 0;
data[2] = 0xFF;
if (flow2state == 0)
{
WireRead(addr2,3,1,data);
if (CrcCheck(data) == 0)
{
int holder = ((data[0] << 8) + data[1]);
holder = -(holder & 32768) + (holder & 32767); // 2's complement from the bytes
flow2Topic = (holder - sensorOffset) / scaleFactor;
}
}
if (Serial.available())
{
char inChar = Serial.read();
switch(inChar)
{
case 'D':
Serial.print("d");
Serial.print(flow1Topic); Serial.print(" ");
Serial.print(flow2Topic); Serial.print(" ");
Serial.print(pressureTopic); Serial.print(" ");
Serial.print(flow1state); Serial.print(" "); Serial.println(flow2state);
break;
case 'Q':
Serial.println("r");
break;
case 'V':
verb = !verb;
if (verb)
{
Serial.println("verbose");
}
else
{
Serial.println("quiet");
}
default:
Serial.println("e");
}
}
else if (verb)
{
Serial.print("Flow Sensor 1: "); Serial.println(flow1Topic);
Serial.print("Flow Sensor 2: "); Serial.println(flow2Topic);
Serial.print("Pressure Sensor: "); Serial.println(pressureTopic);
delay(10);
}
}
// *******************************************************************************************************
void PinSetup()
{
pinMode(FLOW1PWR, OUTPUT);
pinMode(FLOW2PWR, OUTPUT);
pinMode(PRESSUREPIN, INPUT);
digitalWrite(FLOW1PWR, LOW);
digitalWrite(FLOW2PWR, LOW);
}
int WireWrite(uint8_t command[], uint8_t ADDR, int I2CBUS)
{
int command_length = sizeof(command) / sizeof(command[0]);
if (I2CBUS == 0)
{
Wire.beginTransmission(ADDR);
for (int i = 0; i < command_length; i++)
{
Wire.write(command[i]);
}
return Wire.endTransmission(false);
}
else
{
Serial.print("-a.1 ");
Wire1.beginTransmission(ADDR);
for (int i = 0; i < command_length; i++)
{
Wire1.write(command[i]);
}
Serial.print("-a.2 ");
return Wire1.endTransmission(false);
}
}
void WireRead(uint8_t ADDR, int read_length, int I2CBUS, byte data[])
{
Serial.println("-a.1 ");
if (I2CBUS == 1)
{
Serial.println("-b.1 ");
Wire1.requestFrom(ADDR, read_length, false);
for (int i = 0; i < read_length; i++)
{
Serial.println("-b.11 ");
data[i] = Wire1.read();
}
Serial.println("-b.2 ");
}
else
{
Serial.println("-c.1 ");
Wire.requestFrom(ADDR, read_length, false);
for (int i = 0; i < read_length; i++)
{
data[i] = Wire.read();
}
Serial.println("-c.2 ");
}
Serial.println("-a.2 ");
}
byte CrcCheck(byte data[3])
{
byte byteCtr; byte calc_crc = 0;
for (byteCtr = 0; byteCtr < 3; ++byteCtr) {
calc_crc ^= (data[byteCtr]);
for (int i = 8; i > 0; --i) {
if (calc_crc & 0x80) { calc_crc = (calc_crc << 1) ^ 0x131; }
else { calc_crc = (calc_crc << 1); }
}
}
return calc_crc;
}
float GetPressure()
{
float sensorVal = analogRead(PRESSUREPIN);
return ((((sensorVal * VDD / 1023.0 - VDD/2) - VDD / 10) * (120) / (0.8 * VDD) + 60) * 1.02) - 87.5;
}
void FlowOnePwr(bool onoff)
{
if (onoff)
{
digitalWrite(FLOW1PWR, LOW);
}
else
{
digitalWrite(FLOW1PWR, HIGH);
}
}
void FlowTwoPwr(bool onoff)
{
if (onoff)
{
digitalWrite(FLOW2PWR, LOW);
}
else
{
digitalWrite(FLOW2PWR, HIGH);
}
}
void ResetSensor(int option) // 1 for sensor 1, 2 for sensor 2, 3 for both
{
uint8_t data_holder[3];
switch (option)
{
case 1:
FlowOnePwr(false);
delay(5);
FlowOnePwr(true);
delay(2);
WireWrite(commandReset,addr1,0);
delay(2);
WireWrite(commandMeasure,addr1,0);
WireRead(addr1,3,0,data_holder);
WireRead(addr1,3,0,data_holder);
break;
case 2:
FlowTwoPwr(false);
delay(5);
FlowTwoPwr(true);
delay(2);
WireWrite(commandReset,addr2,1);
delay(2);
WireWrite(commandMeasure,addr2,1);
WireRead(addr2,3,1,data_holder);
WireRead(addr2,3,1,data_holder);
break;
case 3:
FlowOnePwr(false);
FlowTwoPwr(false);
delay(5);
FlowOnePwr(true);
FlowTwoPwr(true);
delay(2);
WireWrite(commandReset,addr1,0);
WireWrite(commandReset,addr2,1);
delay(2);
WireWrite(commandMeasure,addr1,0);
WireWrite(commandMeasure,addr2,1);
WireRead(addr1,3,0,data_holder);
WireRead(addr2,3,1,data_holder);
WireRead(addr1,3,0,data_holder);
WireRead(addr2,3,1,data_holder);
break;
}
}