Hi! I have had to clone a few wireless transmitters for my home recently (in my case for several CAME gates). As I'm an absolute beginner in programming, I used a ready-made code (link in the bottom) and added a dab of lines i.a. to save the codes to a microSD... It works with UNO smoothly. Sorry for a few comments in Russian, these are a few memos for myself.
The question is: is there a way (the simpler the better) to have the second HC-12 operating on another frequency work with the SAME Arduino? So I want to listen 433 and 315 MHz simultaneously. So that's gonna be a universal "scanner".
Yes, I know what you are thinking, but no infringement of private property involved. Kindly everyone, for personal use only))
/*
SD card read/write
SD card attached to SPI bus as follows:
MOSI → pin 11
MISO → pin 12
CLK → pin 13
CS → pin 4
*/
#include <SPI.h> // Добавляем библиотеки для записи на карту памяти
#include <SD.h>
File myFile;
/*
DS3231 AT24C32 IIC RTC module
SCL → A5
SDA → A4
VCC → 5V
GND → GND
year, month, date, hour, min, sec and week-day(starts from 0 and goes to 6)
writing any non-existent time-data may interfere with normal operation of the RTC.
Take care of week-day also.
*/
#include <Wire.h> // Добавляем библиотеки для часов реального времени
#include "Sodaq_DS3231.h"
// DateTime dt(2016, 9, 13, 22, 50, 0, 1); //define to initially setup and comment out
char weekDay[][4] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
#define pinRX 2 // HC-12 433 MHz receiver is used
#define pinTX 8 // Not used
#define CM_MAX_TE 450
#define CM_MIN_TE 250
#define CM_BITS12 12
#define CM_BITS24 24
#define Te 320
volatile byte level = 255;
volatile unsigned long last;
volatile unsigned long len;
byte p_level;
unsigned long p_len;
unsigned long p_len_prev;
struct
{
uint8_t state;
uint8_t data[3], dat_bit;
} came;
void setup()
{
Wire.begin();
rtc.begin();
// rtc.setDateTime(dt); //Adjust date-time as defined 'dt' above in setup if needed
Serial.begin(9600);
while (!Serial);
attachInterrupt(0, pinRX_int, CHANGE);
pinMode(pinTX, OUTPUT);
interrupts();
Serial.println("Grabber is running");
// Проверяем работу карты памяти
if (!SD.begin(4)) {
Serial.println("SD initialization failed");
return;
}
Serial.println("SD initialization done");
DateTime now = rtc.now(); //get the current date-time
myFile = SD.open("log.txt", FILE_WRITE);
if (myFile) {
Serial.print("Writing to log.txt...");
Serial.print(' ');
myFile.print("Log started on ");
myFile.print(now.year(), DEC);
myFile.print('/');
myFile.print(now.month(), DEC);
myFile.print('/');
myFile.print(now.date(), DEC);
myFile.print(' ');
myFile.print(now.hour(), DEC);
myFile.print(':');
myFile.print(now.minute(), DEC);
myFile.print(':');
myFile.print(now.second(), DEC);
myFile.print(' ');
myFile.println(weekDay[now.dayOfWeek()]);
// close the file:
myFile.close();
Serial.println("ok.");
} else {
// if the file didn't open, print an error:
Serial.println("Error opening log.txt");
}
}
void loop()
{
//прием (отображается в мониторе серийного порта и записывается в лог на карту памяти)
RfReceive();
//передача (записать код сюда)
// char *code = "000000000000"; // 0-0
// char *code = "111111110110011111100010"; // 0-0-0
// boolean keyUp = digitalRead(5); // кнопка
// if (!keyUp) {
// RfTransmitt(code, 4);
// delay(2000); // сделать паузу между отправками
// }
}
void RfReceive()
{
if (level != 255)
{
noInterrupts();
p_level = level;
p_len = len;
len = 0;
level = 255;
interrupts();
process_came();
p_len_prev = p_len;
}
if (came.state == 100)
{
myFile = SD.open("log.txt", FILE_WRITE);
DateTime now = rtc.now(); //get the current date-time
myFile.print(now.year(), DEC);
myFile.print('/');
myFile.print(now.month(), DEC);
myFile.print('/');
myFile.print(now.date(), DEC);
myFile.print(' ');
myFile.print(now.hour(), DEC);
myFile.print(':');
myFile.print(now.minute(), DEC);
myFile.print(':');
myFile.print(now.second(), DEC);
myFile.print(' ');
myFile.print('#');
myFile.print(' ');
for (int i = 0; i < sizeof(came.data) - (came.dat_bit == CM_BITS12 ? 1 : 0); i++) {
if (i > 0) {
Serial.print("-");
myFile.print("-");
}
Serial.print(stringWithPrefix(String(came.data[i], BIN), came.dat_bit == CM_BITS12 ? 6 : 8, '0'));
myFile.print(stringWithPrefix(String(came.data[i], BIN), came.dat_bit == CM_BITS12 ? 6 : 8, '0'));
}
came.state = 0;
Serial.println();
myFile.println();
myFile.close();
}
}
void RfTransmitt(char *codeString, unsigned int numberOfShipments)
{
int codeLength = strlen(codeString);
if (codeLength != 12 && codeLength != 24)
{
Serial.println("incorrect code.");
return;
}
byte code[codeLength];
for (int i = 0; i < codeLength; i++) {
code[i] = codeString[i] == '0' ? 0 : 1;
}
byte codeUpdate[codeLength];
int number = 0;
switch (codeLength) {
case 12:
//оратный порядок
for (int i = 5; i >= 0; i--) {
codeUpdate[number] = code[i];
Serial.print(codeUpdate[number]);
number++;
}
Serial.print(" ");
//прямой порядок
for (int i = 6; i < 12; i++) {
codeUpdate[number] = code[i];
Serial.print(codeUpdate[number]);
number++;
}
break;
case 24:
//оратный порядок для всех символов
for (int i = 1; i <= 3; i++) {
for (int j = i * 8 - 1; j >= 8 * (i - 1); j--) {
codeUpdate[number] = code[j];
Serial.print(codeUpdate[number]);
number++;
}
Serial.print("-");
}
break;
}
Serial.println();
for (int i = 0; i < numberOfShipments; i++) // посылку посылаем как и брелок - NS раза подряд.
{
digitalWrite(pinTX, HIGH);
delayMicroseconds(Te);
digitalWrite(pinTX, LOW); // посылаем стартовый импульс
for (int j = 0; j < codeLength; j++) {
SendCameBit(codeUpdate[j]); // побитово перебираем и посылаем код
}
delay(16);
}
}
void pinRX_int()
{
if (level != 255) return;
len = micros() - last;
last = micros();
if (digitalRead(pinRX) == HIGH) level = 0;
else level = 1;
}
void process_came()
{
unsigned char b;
switch (came.state)
{
case 0:
if (p_level) break;
came.state = 1;
break;
case 1: //start
if (!p_level) break;
else if (p_len >= CM_MIN_TE && p_len <= CM_MAX_TE)
{
came.state = 2;
came.dat_bit = 0;
for (int i = 0; i < sizeof(came.data); i++) {
came.data[i] = 0x00;
}
}
else came.state = 0;
case 2: //dat
if (p_level)
{
if (came.dat_bit == CM_BITS24)
{
came.state = 0;
break;
}
if (p_len_prev <= CM_MAX_TE && p_len_prev >= CM_MIN_TE &&
p_len <= CM_MAX_TE * 2 && p_len >= CM_MIN_TE * 2) b = 0;
else if (p_len_prev <= CM_MAX_TE * 2 && p_len_prev >= CM_MIN_TE * 2 &&
p_len <= CM_MAX_TE && p_len >= CM_MIN_TE) b = 1;
else
{
came.state = 0;
break;
}
if (b) set_bit(came.data, came.dat_bit);
came.dat_bit++;
break;
}
else
{
if ((p_len > 5000) && (came.dat_bit == CM_BITS12 || came.dat_bit == CM_BITS24)) came.state = 100;
}
break;
}
}
void SendCameBit(byte b)
{
delayMicroseconds(Te);
if (!b) digitalWrite(pinTX, HIGH);
delayMicroseconds(Te);
digitalWrite(pinTX, HIGH);
delayMicroseconds(Te);
digitalWrite(pinTX, LOW);
}
void set_bit(uint8_t *data, uint8_t n)
{
data[n / 8] |= 1 << (n % 8);
}
String stringWithPrefix(String line, int len, char prefix)
{
String addon = "";
int n = len - line.length();
for (int i = 0; i < n; i++) {
addon += prefix;
}
return addon + line;
}
// http://arduino.ru/forum/apparatnye-voprosy/mx-05v-mx-fs-03v-pult-came-top432na