Go Down

Topic: HC-12 TRANSMITTER TO HC-12 RECEIVER, CONVERT ANALOG VALUES BACK TO INTEGER (Read 6859 times) previous topic - next topic

Robin2

I am writing up some code using the parse function (i.e example 4 modified <TR, 1023>) in the serial basics guide provided by Robin2 to try to mimic the same functionality as the code below.

My friends add-ons to my code were working at one point on the receiver end but all I get now are  0s printing on the receiver serial monitor.
He is using the "&" character as a delimiter if my understanding is correct.
If this was my project I would use the code in my Serial Input Basics and I believe it would be working inside an hour.

Start by just receiving the data and printing it to the Serial Monitor.

When that works extend it to parse the data.

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

knightridar

@Robin2 Thanks. I read through the guide more thoroughly.

The code is working for data transmission from one Arduino Uno to another Arduino Uno.

When I hook up the HC-12 to my Arduino Pro Mini for transmission I am able to see that the data is properly being printed on the serial monitor on the transmitter side.

However, on the receiver end the Arduino Uno doesn't get data. The serial monitor shows a blank screen.

My guess is it's not a program issue at this point now but probably
an insufficient power provided to the HC-12 issue. Not 100% sure.
The Arduino Pro Mini is the 3.3V, 8 Mhz version.

I got the completed code for anyone that may need to refer to it or use it written below.

Here is what data looks like on the transmission end:

Code: [Select]

<380,148,224,260,1196,79>


Here is what successful reception of data looks like (between two Arduino Uno's):

Code: [Select]

<732,180,264,290,1272,82>
AZIMUTH MOTOR MOVES COUNTERCLOCKWISE
   
ELEVATION MOTOR MOVES CLOCKWISE



TRANSMITTER CODE:
Code: [Select]

#include <SoftwareSerial.h>

const byte HC12RxdPin = 11;                   // RECEIVE PIN ON HC12
const byte HC12TxdPin = 12;                   // TRANSMIT PIN ON HC12

SoftwareSerial HC12(HC12TxdPin, HC12RxdPin); // CREATE SOFTWARE SERIAL PORT

void setup() {
  HC12.begin(9600); //SERIAL PORT TO HC12
}

void loop() {
  //LIGHT SENSORS CONNNECTED TO ANALOG PIN ON ARDUINO BOARD
  int TR = analogRead(A1); //TOP RIGHT SENSOR
  int BR = analogRead(A0); //BOTTOM RIGHT SENSOR
  int TL = analogRead(A2); //TOP LEFT SENSOR
  int BL = analogRead(A3); //BOTTOM LEFT SENSOR
  int DT = analogRead(A6) * 4; //CONTROL DELAY TIME BETWEEN READINGS OF SENSORS
  int TE = analogRead(A7) / 4; //SET TOLERANCE VALUE FOR DIFFERENCE BETWEEN SENSORS

  HC12.print("<"); //SENDS ANALOG VALUES IN THIS FORMAT: I.E. <380,148,224,260,1196,79>
  HC12.print(TR);
  HC12.print(",");
  HC12.print(BR);
  HC12.print(",");
  HC12.print(TL);
  HC12.print(",");
  HC12.print(BL);
  HC12.print(",");
  HC12.print(DT);
  HC12.print(",");
  HC12.print(TE);
  HC12.print(">");
  HC12.println();

  delay(DT);
}




RECEIVER CODE:

Code: [Select]

#include <SoftwareSerial.h>

const byte HC12RxdPin = 11;                   // RECEIVE PIN ON HC12
const byte HC12TxdPin = 12;                   // TRANSMIT PIN ON HC12

SoftwareSerial HC12(HC12TxdPin, HC12RxdPin);  // CREATE SOFTWARE SERIAL PORT

// AZIMUTH AND ELEVATION PWM PINS ON EACH H-BRIDGE MUST BE CONNECTED TO FOUR PWM (PULSE WIDTH MODULATION) PINS ON ARDUINO.
// FOR UNO/MICRO/PRO MINI THEY ARE: 3,5,6,9,10,11.

int AREN = 2; int ARPWM = 3; int ALEN = 4; int ALPWM = 5; // MOTOR AZIMUTH ADJUSTMENT
int EREN = 7; int ERPWM = 6; int ELEN = 8; int ELPWM = 9; // MOTOR ELEVATION ADJUSTMENT

const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars];        // TEMPORARY ARRAY FOR USE WHEN PARSING

// VARIABLES TO HOLD THE PARSED DATA
int TR = 0; //TOP RIGHT SENSOR
int BR = 0; //BOTTOM RIGHT SENSOR
int TL = 0; //TOP LEFT SENSOR
int BL = 0; //BOTTOM LEFT SENSOR
int DT = 0; //CONTROL DELAY TIME BETWEEN READINGS OF SENSORS
int TE = 0; //SET TOLERANCE VALUE FOR DIFFERENCE BETWEEN SENSORS

boolean newData = false;

//====================

void setup() {
  Serial.begin(9600); //SERIAL PORT TO PC
  HC12.begin(9600); //SERIAL PORT TO HC12
  pinMode(AREN, OUTPUT); pinMode(ARPWM, OUTPUT); pinMode(ALEN, OUTPUT); pinMode(ALPWM, OUTPUT);  //SET ALL MOTOR CONTROL PINS TO OUTPUTS
  pinMode(EREN, OUTPUT); pinMode(ERPWM, OUTPUT); pinMode(ELEN, OUTPUT); pinMode(ELPWM, OUTPUT);
}

void loop() {
  recvWithStartEndMarkers();
  if (newData == true) {
    strcpy(tempChars, receivedChars);
    // THIS TEMPORARY COPY IS NECESSARY TO PROTECT THE ORIGINAL DATA
    // BECAUSE STRTOK() USED IN PARSEDATA() REPLACES THE COMMAS WITH \0
    parseData();
    showParsedData();
    newData = false;
  }

  int avt = (TR + TL) / 2; // AVERAGE VALUE TOP
  int avd = (BL + BR) / 2; // AVERAGE VALUE DOWN
  int avl = (TL + BL) / 2; // AVERAGE VALUE LEFT
  int avr = (TR + BR) / 2; // AVERAGE VALUE RIGHT

  int dv = avt - avd; // AVERAGE DIFFERENCE OF TOP AND BOTTOM LIGHT SENSORS
  int dh = avl - avr;// AVERAGE DIFFERENCE OF LEFT AND RIGHT LIGHT SENSORS

  if (-1 * TE > dh || dh > TE) // CHECK IF THE DIFFERENCE IN LEFT AND RIGHT LIGHT SENSORS IS WITHIN TOLERANCE RANGE
  {
    if (avl > avr) // IF AVERAGE LIGHT SENSOR VALUES ON LEFT SIDE ARE GREATER THAN RIGHT SIDE, AZIMUTH MOTOR ROTATES CLOCKWISE
    {
      digitalWrite(AREN, HIGH); analogWrite(ARPWM, 255); // SET SPEED OUT OF POSSIBLE RANGE 0~255

      digitalWrite(ALEN, HIGH);  digitalWrite (ALPWM, LOW);
      Serial.println("AZIMUTH MOTOR MOVES CLOCKWISE");
      Serial.println("   ");
    }
    else // IF AVERAGE LIGHT SENSOR VALUES ON RIGHT SIDE ARE GREATER THAN ON LEFT SIDE, AZIMUTH MOTOR ROTATES COUNTERCLOCKWISE
    {
      digitalWrite(ALEN, HIGH); analogWrite(ALPWM, 255);
      digitalWrite(AREN, HIGH); digitalWrite(ARPWM, LOW);
      Serial.println("AZIMUTH MOTOR MOVES COUNTERCLOCKWISE");
      Serial.println("   ");
    }
  }
  else if (-1 * TE < dh || dh < TE) //IF DIFFERENCE IS SMALLER THAN TOLERANCE, STOP AZIMUTH MOTOR
  {
    digitalWrite(AREN, LOW);  digitalWrite(ALEN, LOW);
    Serial.println("AZIMUTH MOTOR STOPS");
    Serial.println("   ");
  }

  if (-1 * TE > dv || dv > TE) //CHECK IF THE DIFFERENCE IN TOP/BOTTOM LIGHT SENSORS IS GREATER THAN TOLERANCE
  {
    if (avt > avd) //IF AVERAGE LIGHT SENSOR VALUES ON TOP SIDE ARE GREATER THAN ON BOTTOM SIDE THEN ELEVATION MOTOR ROTATES CLOCKWISE
    {
      digitalWrite(EREN, HIGH); analogWrite(ERPWM, 255);
      digitalWrite(ELEN, HIGH); digitalWrite(ELPWM, LOW);
      Serial.println("ELEVATION MOTOR MOVES CLOCKWISE");
      Serial.println("   ");
    }
    else //IF AVERAGE LIGHT SENSOR VALUES ON BOTTOM SIDE ARE GREATER THAN ON TOP SIDE THEN ELEVATION MOTOR ROTATES COUNTERCLOCKWISE
    {
      digitalWrite(ELEN, HIGH); analogWrite(ELPWM, 255);
      digitalWrite(EREN, HIGH); digitalWrite(ERPWM, LOW);
      Serial.println("ELEVATION MOTOR MOVES COUNTERCLOCKWISE");
      Serial.println("   ");
    }
  }
  else if (-1 * TE < dv || dv < TE) //IF DIFFERENCE IS SMALLER THAN TOLERANCE, STOP ELEVATION MOTOR
  {
    digitalWrite(EREN, LOW);  digitalWrite(ELEN, LOW);
    Serial.println("ELEVATION MOTOR STOPS");
    Serial.println("   ");
  }
  delay(DT);
}

void recvWithStartEndMarkers() {
  static boolean recvInProgress = false;
  static byte ndx = 0;
  char startMarker = '<';
  char endMarker = '>';
  char rc;

  while (HC12.available() > 0 && newData == false) {
    rc = HC12.read();

    if (recvInProgress == true) {
      if (rc != endMarker) {
        receivedChars[ndx] = rc;
        ndx++;
        if (ndx >= numChars) {
          ndx = numChars - 1;
        }
      }
      else {
        receivedChars[ndx] = '\0'; // TERMINATE THE STRING
        recvInProgress = false;
        ndx = 0;
        newData = true;
      }
    }

    else if (rc == startMarker) {
      recvInProgress = true;
    }
  }
}

//===================

void parseData() {   // SPLIT THE DATA INTO ITS PARTS

  char * strtokIndx;  // THIS IS USED BY STRTOK() AS AN INDEX

  strtokIndx = strtok(tempChars, ",");     // GET THE FIRST PART - THE STRING
  TR = atoi(strtokIndx);      // CONVERT THIS PART TO AN INTEGER

  strtokIndx = strtok(NULL, ","); // THIS CONTINUES WHERE THE PREVIOUS CALL LEFT OFF
  BR = atoi(strtokIndx);

  strtokIndx = strtok(NULL, ","); //
  TL = atoi(strtokIndx);

  strtokIndx = strtok(NULL, ","); //
  BL = atoi(strtokIndx);

  strtokIndx = strtok(NULL, ","); //
  DT = atoi(strtokIndx);

  strtokIndx = strtok(NULL, ","); //
  TE = atoi(strtokIndx);
}

//======================

void showParsedData() {  // SHOWS PARSED DATA IN SERIAL MONITOR OUTPUT OF PC
  Serial.print("<");
  Serial.print(TR);
  Serial.print(",");
  Serial.print(BR);
  Serial.print(",");
  Serial.print(TL);
  Serial.print(",");
  Serial.print(BL);
  Serial.print(",");
  Serial.print(DT);
  Serial.print(",");
  Serial.print(TE);
  Serial.print(">");
  Serial.println();
}
Useful CAD/ 3D model files for
Arduino, hobbyist, and engineering projects

https://grabcad.com/has-2

Robin2

When you have a wireless problem simplify simplify.

Try these
Code: [Select]
// TX
#include <SoftwareSerial.h>

const byte HC12RxdPin = 11;                   // RECEIVE PIN ON HC12
const byte HC12TxdPin = 12;                   // TRANSMIT PIN ON HC12

SoftwareSerial HC12(HC12TxdPin, HC12RxdPin); // CREATE SOFTWARE SERIAL PORT

void setup() {
  HC12.begin(9600); //SERIAL PORT TO HC12
}

void loop() {
  //LIGHT SENSORS CONNNECTED TO ANALOG PIN ON ARDUINO BOARD
  static int TR = 24;


  HC12.print("<"); //SENDS ANALOG VALUES IN THIS FORMAT: I.E. <380,148,224,260,1196,79>
  HC12.print(TR);
  HC12.print(">");
  HC12.println();

  delay(500);
  TR += 1;
}



and
Code: [Select]
// RX
#include <SoftwareSerial.h>

const byte HC12RxdPin = 11;                   // RECEIVE PIN ON HC12
const byte HC12TxdPin = 12;                   // TRANSMIT PIN ON HC12

SoftwareSerial HC12(HC12TxdPin, HC12RxdPin);  // CREATE SOFTWARE SERIAL PORT

const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars];        // TEMPORARY ARRAY FOR USE WHEN PARSING

boolean newData = false;

//====================

void setup() {
  Serial.begin(9600); //SERIAL PORT TO PC
  HC12.begin(9600); //SERIAL PORT TO HC12

}

void loop() {
  recvWithStartEndMarkers();
  if (newData == true) {
    Serial.println(receivedChars);
    newData = false;
  }
}

void recvWithStartEndMarkers() {
  static boolean recvInProgress = false;
  static byte ndx = 0;
  char startMarker = '<';
  char endMarker = '>';
  char rc;

  while (HC12.available() > 0 && newData == false) {
    rc = HC12.read();

    if (recvInProgress == true) {
      if (rc != endMarker) {
        receivedChars[ndx] = rc;
        ndx++;
        if (ndx >= numChars) {
          ndx = numChars - 1;
        }
      }
      else {
        receivedChars[ndx] = '\0'; // TERMINATE THE STRING
        recvInProgress = false;
        ndx = 0;
        newData = true;
      }
    }

    else if (rc == startMarker) {
      recvInProgress = true;
    }
  }
}


Note that I have not tested them - but they are unlikely to be too far wrong.

By the way I notice that you have a delay() in loop() in your Rx code - that's a complete NO NO because it could mean that the Rx misses something. Do the timing on the Tx side only.

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

knightridar

I removed the delay time (DT) variable from the receiver code.

Information is easily being transferred from one Arduino Uno to another Arduino Uno.
I then put the transmitter code in the Arduino Pro Mini (3.3 V, 8 Mhz) and
the receiver code into the Arduino Uno (5V, 16 Mhz).
This time around there is no delay time (DT) in the void loop of the code.
Still no transfer of information.

I wanted to see if this was an issue between different models of Arduinos.
So I have the transmitter Arduino Pro Mini (3.3V, 8 Mhz) hooked up outside and transmitting data.
I then uploaded the receiver code to another Arduino Pro Mini (3.3V, 8 Mhz) that's hooked up to my PC and I am monitoring the data through the serial monitor and it works!

Really weird  that two different Arduino models can't talk to each other via the HC-12 modules, but if they are the same model they can talk to each other.
When they are the same models the HC-12 modules are working!
A mystery to me but maybe useful for others if they run into similar issues.

Thanks again everyone!

Here are pictures below:










Here is some sample data from the Receiver Arduino Pro Mini:

Code: [Select]


<964,891,854,972,4056,106>
AZIMUTH MOTOR STOPS
   
ELEVATION MOTOR STOPS
   
AZIMUTH MOTOR STOPS
   
ELEVATION MOTOR STOPS
   
AZIMUTH MOTOR STOPS
   
ELEVATION MOTOR STOPS
   
AZIMUTH MOTOR STOPS
   
ELEVATION MOTOR STOPS
   
AZIMUTH MOTOR STOPS

Useful CAD/ 3D model files for
Arduino, hobbyist, and engineering projects

https://grabcad.com/has-2

Robin2

Really weird  that two different Arduino models can't talk to each other via the HC-12 modules, but if they are the same model they can talk to each other.
That makes me wonder how you are powering the HC12.

If you are drawing power from the Arduino's 3.3v pin that could be the problem - they cannot really supply enough current. Try putting a 10µF capacitor across Vcc and GND on the HC12.

Or, better still, try using a separate 3,3v power supply with a common GND to the Arduino. You could probably use a pair of AA alkaline cells (3v) for testing.

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

knightridar

When I tried using the Arduino Pro mini and sending data to the Arduino Uno,
I tried the method suggested on the site below:

https://www.allaboutcircuits.com/projects/understanding-and-implementing-the-hc-12-wireless-transceiver-module/

I used the recommended range capacitor and diode and I used a separate power supply.
It didn't work. Data transmission was still blank on the receiver end. Weird.

Setups that are working: (Arduino Pro Mini to Arduino Pro Mini or Arduino Uno to Arduino Uno)

Current setup:Arduino Pro Mini to Arduino Pro Mini

Right now I am powering the transmitter end via the Vcc pin with a 5V, 200 mA solar panel.
On a good sunny day the voltage can get up to 5.2~5.4 volts but that's fine since I read the Arduino Pro mini can handle up to 12 volts input.

For the receiver end I am just currently powering it via the 5V usb to ftdi adapter with the jumper set to 3.3v settings.


Transmitting data successfully with devices about 15-20 meters apart.
Useful CAD/ 3D model files for
Arduino, hobbyist, and engineering projects

https://grabcad.com/has-2


PaulS

The art of getting good answers lies in asking good questions.

Go Up