SparkFun Forums 

Where electronics enthusiasts find answers.

General project discussion / help
Did you make a robotic coffee pot which implements HTCPCP and decafs unauthorized users? Show it off here!
By Rescurat
#190347
First let me just say I am a complete noob here and this is my first project.

I am trying to build a simple project that utilizes a piezo transducer to sense vibration and send a signal (RF 433mhz) to a second unit to flash an LED. I am using 5v Pro Micros as my processors, a disk type piezo transducer, LED for visual indicator, and 433mhx tx and rx units. The expected results are that when the piezo senses vibration the Tx unit will turn on/flash the LED and transmit a signal to the Rx unit which will turn on/flash its LED. The actual results are the tx/sensing unit operate as planned, sending the signal to the Rx unit which indeed flashes its LED, the problem is that the LED on the RX unit flashes constantly, (rapid strobe like), in the absence of a signal. I have swapped out Pro Micros and Rx units on the receive side with no change in the problem, I have also removed the RF unit from that setup with the same rapid flash so I don't think I am getting RF noise. Perhaps I have made a mistake in my physical set up or in the code. I am open to any suggestions or code rewrites.

The sensing/Tx unit is configured as follows Pro Micro powered by 9vdc batt to gnd and RAW, Piezo connected to gnd and pin A0 with a 1 Mohm resistor, There is an LED connected to gnd and pin 9 (led has resistor on the + lead), 433 mhz Tx unit is connected VCC to VCC, DATA to pin 4, GND to GND.

The Rx/Notification unit is configured as follows Pro Micro powered by 9vdc batt to gnd and RAW, LED connected to gnd and pin 9 (led has resistor on the + lead), 433 Mhz Rx unit connected DATA to Pin A0, GND to GND, and VCC to VCC.


Sensing/Tx unit code
Code: Select all
/*
Target Sensor Transmit module.
  ------------------------------------------------------------- */
const int ledPin = 9;      // led connected to digital pin 9
const int knockSensor = A0; // the piezo is connected to analog pin 0
const int rfTransmitPin = 4; // rf transmitter connected to pin 4
const int threshold = 400;  // threshold value to decide when the detected sound is a knock or not

int sensorReading = 0;      // variable to store the value read from the sensor pin
int ledState = LOW;         // variable used to store the last LED status, to toggle the light
unsigned long lastPeakTime = 0; //used for calculating peak
int currentPeak = 0;
int blinkCounter = 0;

void setup() {
  pinMode(ledPin, OUTPUT); // declare the ledPin as as OUTPUT
  pinMode(rfTransmitPin, OUTPUT);
  pinMode(knockSensor, INPUT);

  Serial.begin(9600);       // use the serial port for debugging
}

void loop() {
  // read the sensor and store it in the variable sensorReading:
  sensorReading = analogRead(knockSensor);
  if (sensorReading > currentPeak) {
    currentPeak = sensorReading;
  }

  // if the sensor reading is greater than the threshold:
  if (sensorReading >= threshold) {
    Serial.print(sensorReading);
    Serial.println(" Knock! ");

    while (blinkCounter <= 3)
    {
      Serial.println(blinkCounter);
      digitalWrite(rfTransmitPin, HIGH);     //Transmit a HIGH signal
      digitalWrite(ledPin, HIGH);            //Turn the LED on
      delay(500);                           //Wait 

      digitalWrite(rfTransmitPin, LOW);     //Transmit a LOW signal
      digitalWrite(ledPin, LOW);            //Turn the LED off
     
      delay(50);
      digitalWrite(ledPin, LOW);
      delay(50);
      blinkCounter++;
    }
    blinkCounter = 0;
    delay(50);
  }
  //DEBUG CODE THAT GETS WRITTEN TO SERIAL, NOT NECESSARY TO LEAVE IN
  if (millis() - lastPeakTime > 2000) {
    Serial.print("Peak value: ");
    Serial.println(currentPeak);
    lastPeakTime = millis();
    currentPeak = 0;
  }


}
Rx/Signaling Unit Code
Code: Select all
/*
  Target Sensor recieve module.
  ------------------------------------------------------------- */

#define rfReceivePin A0  //RF Receiver pin = Analog pin 0
#define ledPin 9        //Onboard LED = digital pin 9

unsigned int data = 0;   // variable used to store received data
const unsigned int upperThreshold = 70;  //upper threshold value
const unsigned int lowerThreshold = 50;  //lower threshold value

void setup() {
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
}

void loop() {

  data = analogRead(rfReceivePin);  //listen for data on Analog pin 0

  if (data > upperThreshold) {
    digitalWrite(ledPin, LOW);   //If a LOW signal is received, turn LED OFF
    Serial.println(data);
  }

  if (data < lowerThreshold) {
    digitalWrite(ledPin, HIGH);   //If a HIGH signal is received, turn LED ON
    Serial.println(data);
  }
}
By Rescurat
#190365
skimask wrote:...and yet again, no idea what parts are used...
Gee, that was extremely helpful and insightful. All the info I have is included in the post. I thought it was pretty clear...

Second sentence "I am using 5v Pro Micros as my processors, a disk type piezo transducer, LED for visual indicator, and 433mhz tx and rx units." Oh I guess I left out that I also used some wires and a bread board!


Don't bother responding to this unless you truly have some helpful input because I ignore unhelpful idiots that cant read full posts and are only here to flame!

Sincerely

A "One Post Wonder" ignore me if you must
User avatar
By languer
#190367
What skimask is trying to say is that u have not provided which RF transceivers u r using. Based on the post information, the results, and the code, I would guess the RF modules are cheap saw based transmitter and super-regen receiver. These need a lot more code than just serial.write or serial.read. They need some sort of protocol to help the receiver reject the noise. There are literally hundreds of posts on these type of devices. Since u seem to be on the arduino platform, take a very good look at the onewire library. And use the search feature on this forum.
By Rescurat
#190370
The Arduino module is as follows Mini Leonardo Pro Micro ATmega32U4 5V/16MHz Module
and the 433 Mhz pair are as below (copied from the Ebay description)
radio_pair_wm.jpg
Receiver:

Product Model:MX-05V
Operating voltage:DC5V
Quiescent Current:4MA
Receiving frequency:433MHz
Receiver sensitivity: -105 dB
Size:30 * 14 * 7mm
External antenna:32CM single core wire, wound into a spiral

Transmitter:

Product Model:MX-RM-05+
Range : 20-200 meters (different voltages can give different results)
Operating voltage:3.5-12V
Dimensions:19 * 19mm
Operating mode:AM
Transfer rate:4 kB / S
Transmitting power:10mW
Transmitting frequency:433MHz
An external antenna:25cm ordinary multi-core or single-core line
Pin Out from left to right: (DATA, VCC, GND)
You do not have the required permissions to view the files attached to this post.
By skimask
#190373
You can't just send straight serial or On/Off data to those modules. They don't work that way, regardless of what the ebay listing said, or "somebody told you".
Google "Manchester Encoding RF modules"
By Rescurat
#190395
Ok, so I've checked the provided references,(thanks to all that contributed), as well as this one,http://www.hackshed.co.uk/rf-communicat ... -arduinos/.

This has become more than the "simple" project I thought I would be, Tx unit senses vibration via piezo, sends signal to Rx unit and LED flashes...

I have reconfigured my hardware setup connecting the Rx data pin to a digital pin 15,(originally connected to analog per an earlier tutorial I followed). I have also reconsidered the original code, and have come up with the following by combining the knock sensor code and the tx and rx codes from the hackshed article. I believe I'm close to having this right because the flickering LED is gone an about 30% of the time I get the desired response. I don't know if the missed signals are due to corrupt data, or something else... The code I am using transmits a pincode and a number, in this case the pincode is 1 and data# is 5, as I understand it this should allow me to individually address or prevent cross talk between separate pairs if I want to use more than one set of sensor/receivers. I also read that the rx units need a "preamble " to get them ready to accept data, I do not know if the code I'm using has this or how to add it if not.

The components are currently breadboarded and I have added external antennas to the rf units.

Tx unit Piezo is connected to gnd and A0 with a 1Mohm resistor across the legs, 5v LED on pin 9 as a visual indicator for the tx unit, 433 Mhz Tx module gnd-gnd,vcc-vcc, and data-pin 4.

Rx unit has a 5v LED array connected to gnd and pin 9 and the 433 Mhz Rx module is connected gnd-gnd, vcc-vcc, and data-pin 15.
The Arduino module is as follows Mini Leonardo Pro Micro ATmega32U4 5V/16MHz Module
and the 433 Mhz pair are as below (copied from the Ebay description)
radio_pair_wm.jpg


Receiver:

Product Model:MX-05V
Operating voltage:DC5V
Quiescent Current:4MA
Receiving frequency:433MHz
Receiver sensitivity: -105 dB
Size:30 * 14 * 7mm
External antenna:32CM single core wire, wound into a spiral

Transmitter:

Product Model:MX-RM-05+
Range : 20-200 meters (different voltages can give different results)
Operating voltage:3.5-12V
Dimensions:19 * 19mm
Operating mode:AM
Transfer rate:4 kB / S
Transmitting power:10mW
Transmitting frequency:433MHz
An external antenna:25cm ordinary multi-core or single-core line
Pin Out from left to right: (DATA, VCC, GND)


Tx code
Code: Select all
/*
  Target Sensor Transmit module.
  ------------------------------------------------------------- */
#include <VirtualWire.h>
const int ledPin = 9;      // led connected to digital pin 9
const int knockSensor = A0; // the piezo is connected to analog pin 0


const int threshold = 50;  // threshold value to decide when the detected sound is a knock or not

int sensorReading = 0;      // variable to store the value read from the sensor pin
int ledState = LOW;         // variable used to store the last LED status, to toggle the light
unsigned long lastPeakTime = 0; //used for calculating peak
int currentPeak = 0;



void setup() {
  pinMode(ledPin, OUTPUT); // declare the ledPin as as OUTPUT

  pinMode(knockSensor, INPUT);

  Serial.begin(9600);       // use the serial port for debuggin
  vw_set_ptt_inverted(true);
  vw_setup(1200);
  vw_set_tx_pin(4);
}

void loop() {
  // read the sensor and store it in the variable sensorReading:
  sensorReading = analogRead(knockSensor);
  if (sensorReading > currentPeak) {
    currentPeak = sensorReading;
  }

  // if the sensor reading is greater than the threshold:
  if (sensorReading >= threshold) {
    Serial.print(sensorReading);
    Serial.println(" Knock! ");
    sendMessage("1", "5");

    digitalWrite(ledPin, HIGH);            //Turn the LED on
    delay(150);                           //Wait
    digitalWrite(ledPin, LOW);            //Turn the LED off
    delay(150);
    digitalWrite(ledPin, HIGH);            //Turn the LED on
    delay(150);                           //Wait
    digitalWrite(ledPin, LOW);            //Turn the LED off
    delay(150);
    digitalWrite(ledPin, HIGH);            //Turn the LED on
    delay(150);                           //Wait
    digitalWrite(ledPin, LOW);            //Turn the LED off
    delay(150);
    digitalWrite(ledPin, HIGH);            //Turn the LED on
    delay(150);                           //Wait
    digitalWrite(ledPin, LOW);            //Turn the LED off



  }
}

void sendMessage(char* pinCode, char *data) {
  if (strlen(data) > 0) {
    //double startTime = millis();
    //Serial.println("Sending...");
    int msgSize = (strlen(data) + strlen(pinCode) + 1);
    char packetData[msgSize];
    strcat(packetData, pinCode);
    strcat(packetData, ".");
    strcat(packetData, data);

    //Serial.println("Debugging ");
    //Serial.print("Sending Command: ");
    //Serial.print(data);
    //Serial.print(" with Pin Code: ");
    //Serial.print(pinCode);
    //Serial.print("\n");

    vw_send((uint8_t *)packetData, msgSize);
    vw_wait_tx();

    //double endTime = millis();
    //double timeTaken = (endTime - startTime);
    //Serial.print("Time Taken: ");
    //Serial.print(timeTaken);
    //Serial.print(" ms\n");
  }
}
Rx Code
Code: Select all


#include <VirtualWire.h>
#include <string.h>
const int ledPin = 9;      // led connected to digital pin 9
int ledState = LOW;         // variable used to store the last LED status, to toggle the light
byte message[VW_MAX_MESSAGE_LEN];
byte messageLength = VW_MAX_MESSAGE_LEN;

void setup() {
  pinMode(ledPin, OUTPUT); // declare the ledPin as as OUTPUT
  Serial.begin(9600);
  vw_set_ptt_inverted(true);
  vw_setup(1200);
  vw_set_rx_pin(15);
  vw_rx_start();
}

void loop() {
  if (vw_get_message(message, &messageLength)) {
    int command = processResponse((char*)message, 1); //Byte Array Response and Pin Code.
    if (command) {
      Serial.print("Received Command: ");
      Serial.print(command);
      Serial.print("\n");
      digitalWrite(ledPin, HIGH);            //Turn the LED on
      delay(150);                           //Wait
      digitalWrite(ledPin, LOW);            //Turn the LED off
      delay(150);
      digitalWrite(ledPin, HIGH);            //Turn the LED on
      delay(150);                           //Wait
      digitalWrite(ledPin, LOW);            //Turn the LED off
      delay(150);
      digitalWrite(ledPin, HIGH);            //Turn the LED on
      delay(150);                           //Wait
      digitalWrite(ledPin, LOW);            //Turn the LED off
      delay(150);
      digitalWrite(ledPin, HIGH);            //Turn the LED on
      delay(150);                           //Wait
      digitalWrite(ledPin, LOW);            //Turn the LED off

    }
  }
}

int processResponse(char* message, int pinCode) {
  char *p = message;
  char *buf;
  int o = 0;
  int pin;
  int command;

  while ((buf = strtok_r(p, ".", &p)) != NULL)  {
    if (o == 0) {
      pin = atoi(buf);
    } else {
      command = atoi(buf);
    }
    o++;
  }

  if (pinCode == pin && command > 0) {
    return command;
  } else {
    return 0;
  }
}
You do not have the required permissions to view the files attached to this post.