Friday, March 31, 2023

0000 0000 1100 0011

The Dirty Dozen - Part Three - curious HC-SR04 module

Out of the box this week comes an "intermediary" module - it hooks up to the HC-SR04 ultrasonic range finder module, displays the distance in cm, and can then output serial data via UART.

The blurb on the module claims that it is STM8S103 based, but the actual chip is a Nuvoton N76E003AT20, which is pretty obscure but the website gives the following:

N76E003 – a 1T-8051 based series MCU, offers 18 KB Flash ROM, configurable Data Flash and 1 KB SRAM. It supports wide operating voltage of 2.4V to 5.5V, temperature range of -40℃ to 105℃, and high noise immunity of 7KV ESD and 4KV EFT.


The chip needs a special programmer if you'd like to chat to it, but even if you could get to it (i.e. de-solder and find a suitable cradle), I'm really not sure how you would alter the code etc to be a bit friendlier - so that's not likely to happen.

As a result of this weirdness I did the obvious and looked at the serial output. It seems that every half second or so it outputted the following wacky string - "D: XXX\R\N". I'm assuming "D" is distance?

I had to cleave off the XXX (representing the actual distance) using the substring() function, and then convert the result to a number.

It worked, but boy is it clunky!

Here is the complete code which outputs to a coloured 10-segment LED module to visually aid distance indication.

// From https://www.programmingelectronics.com/serial-read/
// by Michael James, also
// many thanks to Nick Gammon for the basis of this code
// http://www.gammon.com.au/serial

const unsigned int MAX_MESSAGE_LENGTH = 12;
String convert;
int distance;
void setup() {
  Serial.begin(9600);
  DDRC = B00011111;
  DDRD = B11111000;
}

void loop() {

  //Check to see if anything is available in the serial receive buffer
  while (Serial.available() > 0)
  {
    //Create a place to hold the incoming message
    static char message[MAX_MESSAGE_LENGTH];
    static unsigned int message_pos = 0;

    //Read the next available byte in the serial receive buffer
    char inByte = Serial.read();

    //Message coming in (check not terminating character) and guard for over message size
    if ( inByte != '\n' && (message_pos < MAX_MESSAGE_LENGTH - 1) )
    {
      //Add the incoming byte to our message
      message[message_pos] = inByte;
      message_pos++;
    }
    //Full message received...
    else
    {
      //Print the message (or do other things)
      convert = (String)message;
      convert = convert.substring(2, 5);
      distance = convert.toInt();

      if (distance > 27) {
        PORTC = B00000001;
        PORTD = B00000000;
      }
      else if (distance > 24) {
        PORTC = B00000011;
        PORTD = B00000000;
      }
      else if (distance > 21) {
        PORTC = B00000111;
        PORTD = B00000000;
      }
      else if (distance > 18) {
        PORTC = B00001111;
        PORTD = B00000000;
      }
      else if (distance > 15) {
        PORTC = B00011111;
        PORTD = B00000000;
      }
      else if (distance > 12) {
        PORTC = B00011111;
        PORTD = B10000000;
      }
      else if (distance > 9) {
        PORTC = B00011111;
        PORTD = B11000000;
      }
      else if (distance > 6) {
        PORTC = B00011111;
        PORTD = B11100000;
      }
      else if (distance > 3) {
        PORTC = B00011111;
        PORTD = B11110000;
      }
      else if (distance > 0) {
        PORTC = B00011111;
        PORTD = B11111000;
      }

      //Reset for the next message
      message_pos = 0;
    }
  }
}

I really want to use this module combo on a robot car to do some auto-parking!

If you like the idea, leave a comment on here or in the comments section of the video below.

Enjoy the Dirty Dozen Part III.




 

No comments:

Post a Comment