0
\$\begingroup\$

I'm working with an RSSV013010W0101-U1930 proximity sensor and an Arduino Nano, and I've run into a recurring error that I have a few hunches on, but can't quite figure out.

The device is meant to count the number of times something enters then leaves its field of view, and display that information on a standard hd44780 16x2 LCD display.

Device Schematic

Whenever an object enters the device's field of view, the proximity sensor asserts a logic low to the Arduino Nano's D2 pin and returns to logic high when its field of view is clear. Additionally, the device can also be configured via UART communication, which is where I discovered the problem.

Aside from power and ground connections, the proximity sensor is connected to the Nano in two places TX/OUT to D2, and RX/IN to D7. This is so that the device can be configured or have its current configuration confirmed via UART communication, which in this case is done with Arduino's SoftwareSerial library.

First off, the device was working perfectly for multiple days, using the code below:

#include <LiquidCrystal.h>
#include <EEPROM.h>
#include <SoftwareSerial.h>
//#define DEBUG

#define PROX_INIT_ADDR 1
#define BATTERY_MONITOR A0
LiquidCrystal lcd(9, 8, 13, 12, 11, 10);        //rs, enable, d4, d5, d6, d7)

byte Battery[] = {
  
  B01110,
  B10001,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111
};

byte Clock[] = {
  B01110,
  B10101,
  B10101,
  B10101,
  B10011,
  B10011,
  B10001,
  B01110
};

byte Pace[] = {
  B00000,
  B00100,
  B01010,
  B10001,
  B00100,
  B01010,
  B10001,
  B00000
};

int movementTimeStart = 0;
int movementTimeEnd = 0;
int movementTimeCheck  = 0;
int totalExerciseTime = 0;
bool movementFlag = false;

unsigned int Seconds = 0;
unsigned int Minutes = 0;

int mouseWheelCounter ;
int previousCount;
void setup() {
  Serial.begin(115200);
  lcd.begin(16,2);
  lcd.createChar(1, Battery);
  lcd.createChar(2, Clock);
  lcd.createChar(3, Pace);
  lcd.setCursor(0,0);
  lcd.print("WELCOME TO");
  lcd.setCursor(0,1);
  lcd.print("CV COUNTER");
  delay(3000);
  lcd.clear();
  
  setupProximitySensor();
  bool distanceCalibrationCheck = EEPROM.read(PROX_INIT_ADDR);
  if(distanceCalibrationCheck != true)
  {
    //runDistanceLearning();
    //EEPROM.write(true, PROX_INIT_ADDR);
  }
  pinMode(2, INPUT);
  delay(30);
  
  //attachInterrupt(digitalPinToInterrupt(2), CrystalDisplay, FALLING);
  Serial.println("SETUP COMPLETE");

}

void loop() {
#ifdef DEBUG
  //Serial.println("looping");
#endif
  lcdPrintBattery();
  if(digitalRead(2) == LOW)
  {
    while(digitalRead(2) == LOW)
    {
      delay(1);
    }
    CrystalDisplay();
  }
  if(mouseWheelCounter != previousCount)
  {
    Serial.println(mouseWheelCounter);
    lcdPrintWheelCount();
  }
  if (movementFlag == true)
  {
    lcdPrintTime();
    movementTimeCheck = millis();
    if((movementTimeCheck - movementTimeEnd) > 3000)
    {
      movementFlag = false;
#ifdef DEBUG
      Serial.println("Movement ended");
#endif
    }
  }
  previousCount = mouseWheelCounter;
}

void lcdPrintWheelCount()
{
  char wheel_buf[] = "";
  sprintf(wheel_buf, "\3: %d", mouseWheelCounter);
  lcd.setCursor(8, 1);
  //lcd.rightToLeft();
  lcd.print(wheel_buf);
#ifdef DEBUG
    Serial.println(wheel_buf);
#endif  
}
void lcdPrintTime()
{
  char time_buf[] = "";
  sprintf(time_buf, "\2 %d:%d", Minutes, Seconds);
  lcd.leftToRight();
  lcd.setCursor(0,1);
  lcd.print(time_buf);
#ifdef DEBUG
    Serial.println("Next movement detected!");
#endif 
}
void CrystalDisplay()
{
  Serial.println("Interrupt Detected");
  mouseWheelCounter++;
  if (mouseWheelCounter == 10000) 
  { 
    mouseWheelCounter=0;
  }
  if(movementFlag == false)
  {
    movementTimeStart = millis(); 
    movementFlag = true;
#ifdef DEBUG
    Serial.println("First movement detected!");
#endif
  }
  else
  {
    movementTimeEnd = millis();
    int exerciseTime = ((movementTimeEnd - movementTimeStart)/1000);
    totalExerciseTime += exerciseTime;
    Seconds = totalExerciseTime % 60;
    Minutes = totalExerciseTime / 60;  
  }
}

void setupProximitySensor()
{
  uint8_t tx_buf[6];
  tx_buf[0] = 0x55;
  tx_buf[1] = 0xC0;
  tx_buf[2] = 0x0A;
  tx_buf[3] = 0x01;
  tx_buf[4] = 0x08;
  tx_buf[5] = 0x28;

  uint8_t special_buf[3];
  special_buf[0] = 0x55;
  special_buf[1] = 0x19;
  special_buf[2] = 0x6E;
  
  SoftwareSerial tempSerial(2, 7);
  tempSerial.begin(9600);
  tempSerial.write(tx_buf, 6);
  //delay(750);
  //tempSerial.write(special_buf, 3);
  tempSerial.end();
  delay(3000);
}

void lcdPrintBattery()
{
  char bat_buf[] = "";
  unsigned int batteryValue = analogRead(BATTERY_MONITOR);
  unsigned int batteryPercent = ((batteryValue * 100)/1023);
  sprintf(bat_buf, "\1%d%%",batteryPercent);
  lcd.setCursor(10, 0);
  lcd.print(bat_buf);
}

void runDistanceLearning()
{
  pinMode(2, INPUT);
  pinMode(7, OUTPUT);
  digitalWrite(7, LOW);
  delay(500);
  digitalWrite(7, HIGH);
  bool readVal = digitalRead(2); 
  bool flipVal = !readVal;
  while(readVal != flipVal)
  {
    readVal = digitalRead(2);
  }
  Serial.println("DISTANCE LEARNING COMPLETED");
  return;
}

I've been testing a PCB for the device, and only now have problems arisen on both the breadboard design and the PCB, those problems being that when I check the voltage on the UART buses, the logic HIGH now reads as 1.2V, rather than 5V.

UART with Prox Sense

One of the proximity sensors I tested was actually becoming quite hot, though I haven't felt a notable temperature rise in the other sensors I tried. I've also checked, checked and checked again all the connections and I'm not finding any short or open circuits. What's more, when I remove the proximity sensor, the Arduino's logic levels return to 5V.

UART Without Prox Sense

This suggests to me that something is damaging the proximity sensors, at least on the PCB, but I can't figure out what, since I cannot find any shorts or opens.

edit: I can confirm now that whatever is going wrong is specifically happening on the PCB setup, though I'm not sure what. The only real difference I've found in terms of continuity is that I'm using a potentiometer on the breadboard to set the contrast of the LCD, while I'm just tying it straight to ground on the PCB (technically there's a voltage divider, but the setup is currently only using a 0 ohm for R1, while R2 is unpopulated)

Oh, and one more thing; I tried running the proximity sensor when not attached to the arduino in any way, and I got this in response:

Proximity Sensor without Arduino

Normally the device only asserts a logic low when something has entered its field of view, but no matter what I do, it's constantly low; jostling it in the breadboard, moving it to new locations, waving my hand over it to see if this one was configured to provide a logic HIGH when something enters its field of view, nothing.

\$\endgroup\$
5
  • \$\begingroup\$ It's unclear from your schematic how exactly are your proximity sensors connected to the circuit, but from your description it sounds like one of the sensors has a short and is bringing the high logic level down. \$\endgroup\$ Apr 12 at 21:06
  • \$\begingroup\$ @EdinFifić I thought something like that too, but if there is one, it doesn't show up on a continuity test. Also, the sensors are all fine while I test them on a breadboard, but break if I move them over to the PCB. That said, I can think of a new possibility; the main difference between the breadboard version and the PCB is that the breadboard version is powered via the Arduino's USB plug, while the PCB is powered via 12V input, regulated down to 5V with an L4940V5. Since that's the only real difference between the two, the cause is likely there \$\endgroup\$
    – E.HP.S
    Apr 17 at 14:04
  • \$\begingroup\$ That is likely the cause, but since I don't have detailed pictures of your setup, I can't tell you for sure. The sensor's absolute maximum rating is 5.5V, and anything above that for a brief moment could easily damage it. The devil is almost always in the details. \$\endgroup\$ Apr 17 at 14:17
  • \$\begingroup\$ @EdinFifić I can't test it yet, but I'm working on a new version with more voltage protection, especially against those initial rushes. I'm honestly pretty mad I didn't add them before, but the datasheet seemed to indicate it didn't need any bypass/decoupling caps. Then again, this datasheet and even the device can be pretty weird \$\endgroup\$
    – E.HP.S
    Apr 17 at 14:22
  • \$\begingroup\$ @EdinFifić Alright, I think I can confirm that the problem in the first design is a transient voltage. I'm still testing to make sure, but the oscilloscope is showing what looks like a very, very brief surge of 12V on the 5V supply line? I'd have thought the regulator wouldn't let that through though \$\endgroup\$
    – E.HP.S
    Apr 18 at 16:36

1 Answer 1

1
\$\begingroup\$

Looks like two CMOS outputs driving the same pin at the same time, not a short per se.

Perhaps Nano’s “input” pin is configured as an output. Attach a 10k resistor to the “input”, drive it with high and low logic levels (not at the same time), and confirm that the “input” follows those levels.

\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.