Wired results with HC-SR04

I am using a HC-SR04 ultrasonic sensor. The I have tested it and it works fine.
In my program I am transferring data over 16 wires to a Raspberry Pi.
If I put the relevant ultrasonic code in the void loop than it works fine.
If I put the relevant ultrasonic code in the in a function and call it in the void loop than half the results are 0 when transmitted to the raspberry pi as if the sensor is seeing nothing. The paradox is that the same results are fine in the serial monitor.
I have tested my code on the raspberry pi side and it works fine.
My code is WIP and some things might look wired, irrelevant, or out of place, they probably have not be coded fully yet.
Working code:

int outputPin = 39;
int aClock = 22;
int rClock = 23;

int type = 0;
int header = 0;
int sign = 0;
int value = 0;
int repeat = 0;

int triggerPin = 52;
int echoPin = 53;

int duration = 0;
int distance = 0;

void setup() {
  // THIS IS THE BOORING SETUP PART FOR THE PROGRAM       SETUP HERE        SETUP HERE      SETUP HERE
  Serial.begin(9600);

//  changePinMode(OUTPUT);
  
  for(int i = 24; i < 40; i++) {
    pinMode(i, OUTPUT);
  }
  
  for(int i = 24; i < 40; i++) {
    digitalWrite(i, LOW);
  }

  for(int i = 24; i < 40; i++) {
    pinMode(i, OUTPUT);
  }
  pinMode(44, OUTPUT);
  pinMode(42, OUTPUT);
  pinMode(43, OUTPUT);

  pinMode(triggerPin, OUTPUT);
  pinMode(echoPin, INPUT);
}

// THIS IS WHERE THE FUN STUFF HAPPENS

void loop() {
  // THIS IS THE LOOPY THING / PART OF TEH PROGRAM            LOOP HERE         LOOP HERE       LOOP HERE
  
//  digitalWrite(aClock, LOW);

  // do the nessary stuff
  digitalWrite(triggerPin, LOW);
  delayMicroseconds(5);
  digitalWrite(triggerPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(triggerPin, LOW);
  
  // duration between pulses
  duration = pulseIn(echoPin, HIGH);
  
  // calculate distance based on duration
  distance = (duration / 2) / 29.1;

  Serial.print(distance);
  Serial.println("cm");
      
  transmit(distance, 1);
//  doRecive();
//  Serial.println();

  type = 0;
  header = 0;
  sign = 0;
  value = 0;
  repeat = 0;
  
  delay(100);
}

// THIS IS THE TRANSMITTING CODE                           TRANSMIT HERE      TRANSMIT HERE     TRANSMIT HERE
void transmit(int val, int sensP) {
  for(int i = 9, x = 39; (i > -1) && (x > 23); i--, x--) {
    digitalWrite(x, bitRead(val, i));
  }
  for(int i = 5, x = 29; (i > -1) && (x > 23); i--, x--) {
    digitalWrite(x, bitRead(sensP, i));
  }
}

// THIS IS THE RECIVE CODE                                 RECIVE HERE        RECIVE HERE       RECIVE HERE
void recive() {
  // type
  if(digitalRead(39) == HIGH) type = type + 2;
  if(digitalRead(38) == HIGH) type = type + 1;

  //header
  if(digitalRead(37) == HIGH) header = header + 4;
  if(digitalRead(36) == HIGH) header = header + 2;
  if(digitalRead(35) == HIGH) header = header + 1;

  //sign
  if(digitalRead(34) == HIGH) sign = sign + 1;

  //value
  if(digitalRead(33) == HIGH) value = value + 256;
  if(digitalRead(32) == HIGH) value = value + 128;
  if(digitalRead(31) == HIGH) value = value + 64;
  if(digitalRead(30) == HIGH) value = value + 32;
  if(digitalRead(29) == HIGH) value = value + 16;
  if(digitalRead(28) == HIGH) value = value + 8;
  if(digitalRead(27) == HIGH) value = value + 4;
  if(digitalRead(26) == HIGH) value = value + 2;
  if(digitalRead(25) == HIGH) value = value + 1;

  //repeat
  if(digitalRead(24) == HIGH) repeat = repeat + 1;
}

void doRecive() {
  recive();

  if(type == 0) {
    if(sign == 1) {
      digitalWrite(42, HIGH);
      digitalWrite(43, LOW);
    }
    else {
      digitalWrite(42, LOW);
      digitalWrite(43, HIGH);
    }
    analogWrite(44, value);
  }
}

// ULTRASONIC SENSOR CODE HERE                                  ULTRASONIC HERE     ULTRASONIC HERE     ULTRASONIC HERE
int ultrasonic() {
  // do the nessary stuff
  digitalWrite(triggerPin, LOW);
  delayMicroseconds(5);
  digitalWrite(triggerPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(triggerPin, LOW);
  
  // duration between pulses
  duration = pulseIn(echoPin, HIGH);
  
  // calculate distance based on duration
  distance = (duration / 2) / 29.1;

  return distance;
}

//int changePinMode(boolean mode) {
//  for(int i = 24; i < 40; i++) {
//    pinMode(i, mode);
//  }
//}

Buggy code:

int outputPin = 39;
int aClock = 22;
int rClock = 23;

int type = 0;
int header = 0;
int sign = 0;
int value = 0;
int repeat = 0;

int triggerPin = 52;
int echoPin = 53;

int duration = 0;
int distance = 0;

void setup() {
  // THIS IS THE BOORING SETUP PART FOR THE PROGRAM       SETUP HERE        SETUP HERE      SETUP HERE
  Serial.begin(9600);

//  changePinMode(OUTPUT);
  
  for(int i = 24; i < 40; i++) {
    pinMode(i, OUTPUT);
  }
  
  for(int i = 24; i < 40; i++) {
    digitalWrite(i, LOW);
  }

  for(int i = 24; i < 40; i++) {
    pinMode(i, OUTPUT);
  }
  pinMode(44, OUTPUT);
  pinMode(42, OUTPUT);
  pinMode(43, OUTPUT);

  pinMode(triggerPin, OUTPUT);
  pinMode(echoPin, INPUT);
}

// THIS IS WHERE THE FUN STUFF HAPPENS

void loop() {
  // THIS IS THE LOOPY THING / PART OF TEH PROGRAM            LOOP HERE         LOOP HERE       LOOP HERE
  
//  digitalWrite(aClock, LOW);

  Serial.print(ultrasonic());
  Serial.println("cm");
      
  transmit(ultrasonic(), 1);
//  doRecive();
//  Serial.println();

  type = 0;
  header = 0;
  sign = 0;
  value = 0;
  repeat = 0;
  
  delay(100);
}

// THIS IS THE TRANSMITTING CODE                           TRANSMIT HERE      TRANSMIT HERE     TRANSMIT HERE
void transmit(int val, int sensP) {
  for(int i = 9, x = 39; (i > -1) && (x > 23); i--, x--) {
    digitalWrite(x, bitRead(val, i));
  }
  for(int i = 5, x = 29; (i > -1) && (x > 23); i--, x--) {
    digitalWrite(x, bitRead(sensP, i));
  }
}

// THIS IS THE RECIVE CODE                                 RECIVE HERE        RECIVE HERE       RECIVE HERE
void recive() {
  // type
  if(digitalRead(39) == HIGH) type = type + 2;
  if(digitalRead(38) == HIGH) type = type + 1;

  //header
  if(digitalRead(37) == HIGH) header = header + 4;
  if(digitalRead(36) == HIGH) header = header + 2;
  if(digitalRead(35) == HIGH) header = header + 1;

  //sign
  if(digitalRead(34) == HIGH) sign = sign + 1;

  //value
  if(digitalRead(33) == HIGH) value = value + 256;
  if(digitalRead(32) == HIGH) value = value + 128;
  if(digitalRead(31) == HIGH) value = value + 64;
  if(digitalRead(30) == HIGH) value = value + 32;
  if(digitalRead(29) == HIGH) value = value + 16;
  if(digitalRead(28) == HIGH) value = value + 8;
  if(digitalRead(27) == HIGH) value = value + 4;
  if(digitalRead(26) == HIGH) value = value + 2;
  if(digitalRead(25) == HIGH) value = value + 1;

  //repeat
  if(digitalRead(24) == HIGH) repeat = repeat + 1;
}

void doRecive() {
  recive();

  if(type == 0) {
    if(sign == 1) {
      digitalWrite(42, HIGH);
      digitalWrite(43, LOW);
    }
    else {
      digitalWrite(42, LOW);
      digitalWrite(43, HIGH);
    }
    analogWrite(44, value);
  }
}

// ULTRASONIC SENSOR CODE HERE                                  ULTRASONIC HERE     ULTRASONIC HERE     ULTRASONIC HERE
int ultrasonic() {
  // do the nessary stuff
  digitalWrite(triggerPin, LOW);
  delayMicroseconds(5);
  digitalWrite(triggerPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(triggerPin, LOW);
  
  // duration between pulses
  duration = pulseIn(echoPin, HIGH);
  
  // calculate distance based on duration
  distance = (duration / 2) / 29.1;

  return distance;
}

//int changePinMode(boolean mode) {
//  for(int i = 24; i < 40; i++) {
//    pinMode(i, mode);
//  }
//}

so you write 0 or 1s to the lines and don't even keep the values there for a short while as you immediately overwrite them with sending the sensor number on the low side of the same lines? Even weirder as you write them one after the other the higher bits are ready before the lower bits and right after you overwrite them.... How can you guarantee your raspberry is perfectly synchronized to read which data?

You should have some kind of a clock signal on a separate wire going high instructing the raspberry that data are there to read and keep them on for a little while, then your clock goes low, you write the other value and put your clock High again for a little while.

I am working on a clock right now. As is said WIP.

At the moment (the version you can see) the raspberry pi does not need to be perfectly in sync because the time difference between the updates is so long.

I sent the data as binary. It uses no standard format because I don't have to and I don't want to waste clock with unnecessary characters.

The data stays in the wires until it is updated. In the version you see 10 times a second.

Hi,
Any reason for using parallel, instead of serial coms?

Tom... :slight_smile:

Yes. The Raspberry Pi 3b has serial and I2C issues

Hi,

135843:
Yes. The Raspberry Pi 3b has serial and I2C issues

What serial issues.
You are level shifting the 5V arduino output to the 3.3V Pi inputs?
https://create.arduino.cc/projecthub/sankarCheppali/interfacing-arduino-with-raspberry-pi-6d9870
Just one of many serial comms hits on google
Tom... :slight_smile:

I used a voltage divider whilst testing.

At the moment (the version you can see) the raspberry pi does not need to be perfectly in sync because the time difference between the updates is so long.

sure you might maintain the PIN values for a "long" time

// THIS IS THE TRANSMITTING CODE                           TRANSMIT HERE      TRANSMIT HERE     TRANSMIT HERE
void transmit(int val, int sensP) {
  for(int i = 9, x = 39; (i > -1) && (x > 23); i--, x--) {
    digitalWrite(x, bitRead(val, i));
  }
  for(int i = 5, x = 29; (i > -1) && (x > 23); i--, x--) {
    digitalWrite(x, bitRead(sensP, i));
  }
}

but the 2 for loop writes into PINs sequentially. so do you "wait" long enough on the Raspberry side to know the data is all there? or how can you know the Arduino is not just writing those as you read?