time issue: millis() not properly used?

Why is sleep mode (22uA) not an option.
Leo..

Wawa:
Why is sleep mode (22uA) not an option.
Leo..

The purpose is to install the HC12 in a handheld portable device where 115200 baud will be needed while sleep mode (FU2 setting) supports max 4800 baud. Also the transmission delay will be 500ms to wake up; now I get a 20ms or less delay.

I read in the datasheet that 22uA sleep mode (not FU2) "doesn’t allow serial port data transmission."
You could be right that waking to default mode (FU3) takes some time.
I don't see any timing in the datasheet.

I should study your code first before asking things.
I see you are using SofwareSerial (9600). Not sure if 115200 will work with that.
Changing the baud rate to 115200 after each power-up migh take longer than sending a few bytes at 9600.
Leo..

Hi Leo, the 9600 baud is set to debug the testing program. When running at 115200 baud the transmission duration is so short that a .1uF cap is able to act as a buffer preventing voltage drop below 3.3V (see picture).
EDIT: However delay time between power-up and TX for reliable transmission increases to minimum 40ms.
EDIT2: the baudrate is to remain fixed (115200)

brice3010:
the baudrate is to remain fixed (115200)

So the baud rate written to the module (AT+B115200) stays in memory after a power cycle?
The datasheet doesn't mention anything about that.
I should start playing with these modules myself.
Used about 100 last month for a client, but they are only used in default mode.
Leo..

Wawa:
So the baud rate written to the module (AT+B115200) stays in memory after a power cycle?
(...)
Leo..

Yes. As you can see from the screenshot in my post #23.

Wawa:
(...)
Used about 100 last month for a client, but they are only used in default mode.
Leo..

Interesting Leo, what kind of business are you in?

brice3010:
Interesting Leo, what kind of business are you in?

I build custom circuit boards for clients.
This was a pager/alarm project for a resthome.
In this case the client did the coding.
Leo..

Wawa:
I build custom circuit boards for clients.
This was a pager/alarm project for a resthome.
In this case the client did the coding.
Leo..

That is interesting; fo you design the hardware too?

I do design with EagleCad, but also not in this case.
Latest personal project here.
https://forum.arduino.cc/index.php?topic=495168.0
Leo..

Just realised that you must be switching positive/power of the HC-12.
I think you can't (or shoudn't) do that.

RX/TX pins of the Arduino are normally HIGH (TTL logic) with serial/softwareSerial.
Current will be constantly flowing from both Arduino RX/TX pins into the RX/TX pins of an unpowered HC-12.

Better to switch ground of the HC-12 (if possible with a small n-channel mosfet).
You still can use that cap across the supply of the HC-12.
Leo..

Wawa:
Just realised that you must be switching positive/power of the HC-12.
I think you can't (or shoudn't) do that.

RX/TX pins of the Arduino are normally HIGH (TTL logic) with serial/softwareSerial.
Current will be constantly flowing from both Arduino RX/TX pins into the RX/TX pins of an unpowered HC-12.

Better to switch ground of the HC-12 (if possible with a small n-channel mosfet).
You still can use that cap across the supply of the HC-12.
Leo..

I am not so sure about this: I think the TX and RX pins are part of a serial transmission line based on the RS232 standard, so with a 7k (approx) input impendance for the RX side and emitter follower (I think) for TX. Now for the HC12 used here, the TX has no role on the remote transmitter: data to be sent comes in on the RX pin.
The HC12 datasheet says 1k series resisotrs are used for both TX and RX. The UART used on the HC-12 microcontroller (STM8S003F3) uses no interface, so indeed straight TTL.
The RX pin on the HC12 is high when not used for transmission, I measured current draw (mA) on both RX and TX pins, both when supply voltage is high and low, and also either the GND wire used are open.

GND no GND
5V 0V 5V 0V
RX pin:0.01 0.12 0.01 0.12
TX pin:3.0 3.0 0.001 2.5

Conclusion: what matters here is the current draw when 0V is applied to the HC12; I notice almost no difference with GND used or open for RX (which is actually used to transmit the data in this test). In fact, more current is used when no power is applied! For the TX pin almost no difference when supply voltage is 0V between GND used or GND open.
But: between 5V supply and GND open, and 0V supply and GND used, there is a difference of 3.0 - 0.001 mA.
However, in the FU3 mode I use, 16mA is continually drawn, so there is an advantage in removing the Supply voltage between transmissions.

This becomes another matter however if the FU1 mode (moderate power saving mode) where current draw is 3.6mA between transmissions. In that case it looks like you are right in opening the GND connection.

With softwareSerial, pin4 of the Arduino gives a solid digital HIGH when idle (not just a pull up resistor).
Tested with an Uno clone.
When you disconnect + power to the HC-12, you're effectively feeding a solid 5volt only into the RX pin.
And because you're switching module power with an output pin, module supply is firmly grounded.
Current is only limited by the internal (1K) resistor and other internals of the HC-12.
Switching (disconnecting) ground when the module is not used seems a lot safer.
Then all pins are at 5volt potential.
Leo..

Wawa:
With softwareSerial, pin4 of the Arduino gives a solid digital HIGH when idle (not just a pull up resistor).
Tested with an Uno clone.
When you disconnect + power to the HC-12, you're effectively feeding a solid 5volt only into the RX pin.
And because you're switching module power with an output pin, module supply is firmly grounded.
Current is only limited by the internal (1K) resistor and other internals of the HC-12.
Switching (disconnecting) ground when the module is not used seems a lot safer.
Then all pins are at 5volt potential.
Leo..

I found out that softwareSerial has issues beyound 57600 baud (and I need 115200 baud), so I need to go to another serial function. If I use the hardware serial I will not be able to watch the serial monitor (needed for debugging): what alternative would you use?

brice3010:
If I use the hardware serial I will not be able to watch the serial monitor (needed for debugging): what alternative would you use?

I don't see why you can't send the same data to the serial/USB chip and the HC-12 module
(MCU TX > HC-12 RX).
Leo..

I would use an Arduino that has a native USB and a hardware serial. Start with a Micro and, if you need more horsepower, move up to a Teensy 3.2.

Wawa:
I don't see why you can't send the same data to the serial/USB chip and the HC-12 module
(MCU TX > HC-12 RX).
Leo..

Hi Leo, here is the code I use to receive over the TX and RX on pins 0 and 1 of the Arduino Uno. Nothing is being received when using the HC12 (I connect the HC12 TXD to pin 0 on Arduino, the RX pin). When using a wired link (TX -> RX pins) then receipt=ok.
When I use the same code adapted to HC12 and with SoftwareSerial then it is ok too.

What is wrong with my code for reception over the RX Arduino pin 0 with the HC12?

// http://forum.arduino.cc/index.php?topic=499210.msg3407044#msg3407044
// http://forum.arduino.cc/index.php?topic=396450.0

// HC12 Communication between Arduinos

/*
  This program serves to send one integer (or byte) only from two different HC12
  transmitters at one sensor each (A and B)to one HC12 receiver at the central
  controller Arduino. The receiving HC12 has to know from which transmitter A or B
  the value comes.
  The data are sent with start- and endmarkers

  v5: two integers used, one for the sensor value (integer1FromPC) and one
  for the sensor identifier (integer2FromPC). At the transmitter the sensor A or B are
  identiefied by reading two digital inputs connected to a dipswitch with
  2 switches (max: 4 different sensor/transmitters).

  // RECEIVER PART
*/
/*
#include <SoftwareSerial.h>
const byte HC12RxdPin = 4;                  // Recieve Pin on HC12
const byte HC12TxdPin = 5;                  // 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
// variables to hold the parsed data
char messageFromPC[numChars] = {0};
int integer1FromPC;
int integer2FromPC;
static int previousInteger1FromPC;
static int previousInteger2FromPC;
float floatFromPC = 0.0;

boolean newData = false;

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

void setup()
{
  Serial.begin(115200);
  //HC12.begin(115200);       // Open serial port to HC12

  // declare pin 10, 11 & 12 as output
  pinMode (10, OUTPUT); // sensor value from A
  pinMode (11, OUTPUT); // sensor value from B
  pinMode (12, OUTPUT); // data being received
  pinMode (9, OUTPUT); // data received is different from previous data
  delay(100);
}

void loop() {

  const int interval2 = 150;
  static unsigned long previousMillis2;

  recvWithStartEndMarkers();
  if (newData == true) {
    strcpy(tempChars, receivedChars);
    //Serial.println(receivedChars); // serial monitor output
    // this temporary copy is necessary to protect the original data
    //   because strtok() used in parseData() replaces the commas with \0
    parseData();
    useParsedData();
    if (newData == true) {
      if (integer1FromPC == integer2FromPC) {
        digitalWrite (9, HIGH); // new data different from previous data
        previousMillis2 = millis();
      }
    }
    newData = false;

  }
  if (digitalRead(9) == HIGH) {
    if (millis() - previousMillis2 >= interval2) {
      digitalWrite (9, LOW);
    }
  }
}

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

void recvWithStartEndMarkers() {

  static boolean recvInProgress = false;
  static byte ndx = 0;
  char startMarker = '<';
  char endMarker = '>';
  char rc;
  static unsigned long previousMillis1; // timer
  static const int interval1 = 100;
  boolean rxStatus = false;
  boolean ledState = false;


  while (Serial.available() > 0 && newData == false) {
    rc = Serial.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;
      digitalWrite(12, HIGH); // new data received
      previousMillis1 = millis();
      //    previousInteger1FromPC = integer1FromPC;
    }
  }

  if (digitalRead(12) == HIGH) {
    if (millis() - previousMillis1 >= interval1) {
      digitalWrite(12, LOW);
    }
  }
}


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

void parseData() {      // split the data into its parts

  previousInteger1FromPC = integer1FromPC;
  previousInteger2FromPC = integer2FromPC;

  char * strtokIndx; // this is used by strtok() as an index. It creates the variable
  // strkIndx as a pointer to a variable of type char. It can hold the address of a
  // variable of type char.
  /*
    strtokIndx = strtok(tempChars, ",");     // get the first part - the string
    strcpy(messageFromPC, strtokIndx); // copy it to messageFromPC

    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    integer1FromPC = atoi(strtokIndx);     // convert this part to an integer
    /*
        strtokIndx = strtok(NULL, ",");
        floatFromPC = atof(strtokIndx);     // convert this part to a float
  */

  strtokIndx = strtok(tempChars, ",");     // get the first part - the string
  integer1FromPC = atoi(strtokIndx);     // convert this part to an integer

  strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
  integer2FromPC = atoi(strtokIndx);     // convert this part to an integer

  strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
  strcpy(messageFromPC, strtokIndx); // copy it to messageFromPC


}
//============

void useParsedData() {
  if (messageFromPC[0] == 'A') analogWrite (10, integer1FromPC);
  if (messageFromPC[0] == 'B') analogWrite (11, integer2FromPC);
}

brice3010:
Nothing is being received when using the HC12 (I connect the HC12 TXD to pin 0 on Arduino, the RX pin).
When I use the same code adapted to HC12 and with SoftwareSerial then it is ok too.

Seems the 3.3volt logic signals of the HC-12 can't coexist with the MCU<>USB serial signals.
Live with the lower baud rate, or upgrade the processor.
Leo..

Wawa:
Seems the 3.3volt logic signals of the HC-12 can't coexist with the MCU<>USB serial signals.
Live with the lower baud rate, or upgrade the processor.
Leo..

Leo, where does it say the HC12 uses 3.3V logic? Page 3 of the manuel reads "The STM8S provides a transparent serial data
interface for interfacing to the module, allowing two HC-12 modules to act like
a wired TTL level serial cable without any attached hardware devices needing to
be aware of the RF link."
I tried the receiver board with a 6V battery, same issue. When I attach a scope on the receiver HC12 TX pin (the one receiving data from the transmitter HC12) I see nice spikes from the line 5V to 0V when open, but when connected to the Aruino those spikes are going nowhere below 4V.

2016-01-14_122335_HC-12_v2.3B.pdf (237 KB)

I have to find the time to properly analyse this module.
A quick measure of the RX pin (pin3) showed ~3.3volt (3.3volt logic).
The TX pin however has full supply voltage on it.
Both measured unloaded.
Leo..