Go Down

Topic: Emulate TTL 9600-8-N-1 (MB7380 ultrasonic sensor) with digitalWrite() (Read 428 times) previous topic - next topic

One ultrasonic sensor (MB7380) is operating with TTL. I want to send the same signal that this sensor would output, as a sweep. In other words, please help with writing code for sweeping from where the sensor would read 0 to near the maximum range (roughly 5-meters).

I've taken an introductory EE logic course; so either understanding this wasn't covered or I'm over-complicating it. A datalogger board will be reading the 9600 baud TTL signal. (That is how I will be confirming it sends the desired signals.)

More specifically, the sensor uses the signal pins 4 and 5. The datasheet above has details.
How was this sensor connected to the datalogger? Someone else, out-of-house, did that before me. I have their contact info if I should need to ask certain questions. (I Googled and tried finding a solution myself, but no progress.)



Code: [Select]

/*
Test rig -- output ~ simulates sensors -- to Q4 datalogger
*/
#include<LiquidCrystal.h>

unsigned long startMillis;
unsigned long currentMillis;
const unsigned long period = 1000;
int pinAnalog = 2;
int pinDigital = 3;
int pinOneWire = 4;

LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // Arduino pins. Creates object
    // LCD pin (RS enable D4 D5 D6 D7) parameters

void setup() {
  Serial.begin(9600);
  lcd.begin(20, 4);
 
  startMillis = millis();  //initial start time
 
  // pinMode not needed for OUTPUT operator
  pinMode(8, INPUT);
  pinMode(9, INPUT);
  pinMode(10, INPUT);
  pinMode(11, INPUT);
  pinMode(12, INPUT);
  pinMode(13, INPUT);
  pinMode(14, INPUT);
  pinMode(15, INPUT);

  pinMode(2, INPUT);
  pinMode(3, INPUT);
  pinMode(4, INPUT);
}

void loop() {
  currentMillis = millis(); // milliseconds since start
 
  lcd.setCursor(0, 0);
  lcd.print("Welcome.");
  lcd.setCursor(0, 1);
  lcd.print("Ready to make a selection.");
 
  analogSelection = digitalRead(pinAnalog);   // 2
  digitalSelection = digitalRead(pinDigital); // 3
  oneWireSelection = digitalRead(pinOneWire); // 4

  if(analogSelection == HIGH)
  {
    currentMillisA = millis();
    if(currentMillisA - startMillis > 1000*60) // one min.
    {
      lcd.clear();
      lcd.setCursor(0, 0);        // 1st line
      lcd.print("Testing...");
      lcd.setCursor(0, 1);        // 2nd
      lcd.print("Analog inputs");
      lcd.setCursor(0, 2);        // 3rd
      lcd.print("Please wait 4 min.");     
      for(int pin = 0; pin < 8; pin++)
        for(int s = 63; s <= 255; s += 64)
          {          // PWM: 255 = 5V
            analogWrite(pin, s);      // sweeps 1.24, 2.5, 3.75 & 5V
            startMillis = currentMillis;  //IMPORTANT to save start time of current state
         }
    }
  }
  else if(digitalSelection == HIGH)
  {
    // DO - User toggled switch to simulate the ultrasonic sensor.
  }
  else if(oneWireSelection == HIGH)
  {
    currentMillis1 = millis();
    if(currentMillis1 - startMillis > 1000*60) // one min.
    {
      // TODO
      startMillis = currentMillis1;  //IMPORTANT to save start time of current state   
    }
  }
  else
    // error message for multiple inputs at once
}



This is what I have so far. Note, none of it so far is for the digital TTL GPIO. (I think I created a simple voltage sweep for the analog pins of the datalogger board. Corrections and related comments are welcome =) If it matters, I'm using the Mega2560.

groundFungus

Quote
pinMode not needed for OUTPUT operator
The inputs default to INPUT.  So pinMode(pin, INPUT) is not needed.   For a pin to be an output it must be set to output with pinMode(pin, OUTPUT).

If you want too output a serial signal, why not use one of the extra serial ports of the Mega.

pylon

As you don't do any time critical task in your loop() this is an example where you might use SoftwareSerial.

As I understand your description you'll only use the TX signal, so you can use any pin for RX.

As a non-native speaker, what's sweep in this context? My translation tells me something with cleaning but that makes no sense in your sentence.

As I understand your description you'll only use the TX signal, so you can use any pin for RX.

What about it? How? I am new to this.

As a non-native speaker, what's sweep in this context? My translation tells me something with cleaning but that makes no sense in your sentence.
To go from one end to the other. For example, a voltage sweep could be sweeping from 0-5V (within a range, to go from minimum to maximum). This can be done in increments to the maximum: 0, 1V, 2V, 3V, 4V, 5V. It could be logarithmic too.

pylon

I don't understand your pin configuration diagram. What are the colors for? What do the key terms mean? They are not the Mega2560 pins, aren't they?

Quote
What about it? How? I am new to this.
The sensor provide a basic TTL asynchronous serial signal. So it's the same as the serial signal you use to communicate from the PC to the Arduino. You could use one of the 4 hardware serial interfaces to put out that signal or if you already fixed the pins where that has to be connected, you could use the SoftwareSerial library to provide that functionality by serial emulation.

You just have to write the correct bytes to the corresponding serial interface. Try to do that, post your code and tell us the problems you might have. Don't expect us to write the code for you.

Quote
To go from one end to the other. For example, a voltage sweep could be sweeping from 0-5V (within a range, to go from minimum to maximum). This can be done in increments to the maximum: 0, 1V, 2V, 3V, 4V, 5V. It could be logarithmic too.
Thanks for the explanation. I'm eager to learn!

I don't understand your pin configuration diagram. What are the colors for? What do the key terms mean? They are not the Mega2560 pins, aren't they?
Those are the pins of the datalogger. The colors mean nothing. The sensor goes to those pins.
To emulate the sensor, I will disconnect it. Then, I need to connect the Ardunio pins to those pins. They're GPIO (not SPI--because only two lines are connected for each ultrasonic sensor). 

You just have to write the correct bytes to the corresponding serial interface. Try to do that, post your code and tell us the problems you might have. Don't expect us to write the code for you.
That helps a little. My main question is how do I output a certain distance. For example, what distance is 0.5 feet (0.15m)? I will continue looking into the SoftwareSerial library...but I still have a very vague idea on where to go from "just have to write the correct bytes."

Robin2

I've taken an introductory EE logic course; so either understanding this wasn't covered or I'm over-complicating it. A datalogger board will be reading the 9600 baud TTL signal.
An Arduino Mega can produce that output on pin 18 with Serial1.write() - assuming you have Serial1.begin(9600); in setup()

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

pylon

Quote
For example, what distance is 0.5 feet (0.15m)?
For that you have to print the following string: "R0150\r".

Quote
I will continue looking into the SoftwareSerial library.
Don't use that library in your case. Use the hardware serial interfaces (Serial1, Serial2) instead.

Use the hardware serial interfaces (Serial1, Serial2) instead.
Serial.write(R0150\r);
or
int bytesSent = Serial.write(R0150\r);
or
Something more complicated?

pylon

Code: [Select]
Serial.write(R0150\r);

No, the double quotes are necessary. But you should first learn to do simple Arduino programming before you start to emulate sensors. Experiment with you Arduino and learn the basic C(++) programming. Once you know what a C-string is and how arrays are used you could start with the project you describe here. Don't expect us to write the complete code for you. As you have proofed above you currently have no programming skills so this project is not at your level.

I have programming experience. No, pylon, I don't expect anyone to "write the code" for me, said multiple times.

Code: (C) [Select]

void setup() {
 
  Serial.begin(9600); // bps ~ baud rate
  delay(50);
}

void loop() {
    Serial.write("R0030");  // 30 mm = 1.2" = 0.1'
    Serial.write('\r');     // "\r" (stop bit) carriage return
      delay(60000);         // takes a minute to show on graph
   
    Serial.write("R0061");  // 0.2 feet
    Serial.write(0x0d);     // hex
      delay(60000);
    Serial.write("R0091");  // 0.3 feet
    Serial.write(13);       // ASCII
      delay(60000);
    Serial.write("R0122");  // 0.4 feet
    Serial.write(13);
      delay(60000);
    Serial.write("R0152");  // 0.5 feet
    Serial.write(13);
      delay(60000);
    Serial.write("R0183");  // 0.6 feet
    Serial.write(13);
      delay(60000);
    Serial.write("R0213");  // 0.7 feet
    Serial.write(13);
    Serial.end();
}
 


Wondering what pin to connect..."TX0→1"?


pylon

Quote
Wondering what pin to connect..."TX0→1"?
With above code you would have to do anything like that (pin 1 of the Mega provides the serial output signal, connect that to the receiving pin on that logger board). But I would suggest to change every occurrence of "Serial" to "Serial1". Then you have to use pin 18 instead of pin 1 and you can use the standard USB to serial channel to do debugging.

Quote
The word is "proved."
Thank you, try to remember it.

Quote
And again, you're assuming a lot from very little.
Might be, please excuse If I was wrong.

DrAzzy

IMO, there's a case to be made for using Serial instead of Serial1. Why? So you can connect to the serial monitor at 9600 baud and see what's being sent - the arduino's TX line would be going to both the adapter on the board, and the datalogger.
ATTinyCore for x4/x5/x61/x7/x8/x41/1634/828/x313 megaTinyCore for the megaavr ATtinies - Board Manager:
http://drazzy.com/package_drazzy.com_index.json
ATtiny breakouts, mosfets, awesome prototyping board in my store http://tindie.com/stores/DrAzzy

Go Up