Пример создания скетча датчика тока GY712 для MySensors
Добавлено: 01 ноя 2017, 18:23
Обратился к сообществу человек, с вопросом: "Есть ли скетч для работы датчика тока GY712 с передачей данных по протоколу MySensors". И я решил создать пост с примером, как создать свой скетч для работы с MyS, на основании скетча найденного в сети и руководства по созданию сообщений для отправки. И так имеем:
тремя звёздочками и между множеством звёздочек отмечены строки, которые были добавлены мной в приведённый выше скетч
P.S. Скетч в работе не проверялся, т.к. нет данного датчика для теста. Буду рад если отзовётся тот кто сможет потестить.
Код: Выделить всё
#define CURRENT_SENSOR A0 // Analog input pin that sensor is attached to
float amplitude_current; //amplitude current
float effective_value; //effective current
void setup()
{
Serial.begin(9600);
pins_init();
}
void loop()
{
int sensor_max;
sensor_max = getMaxValue();
Serial.print("sensor_max = ");
Serial.println(sensor_max);
//the VCC on the Grove interface of the sensor is 5v
amplitude_current=(float)(sensor_max-512)/1024*5/185*1000000;// for 5A mode,you need to modify this with 20 A and 30A mode;
effective_value=amplitude_current/1.414;
//minimum_current=1/1024*5/185*1000000/1.414=18.7(mA)
//Only for sinusoidal alternating current
Serial.println("The amplitude of the current is(in mA)");
Serial.println(amplitude_current,1);//Only one number after the decimal point
Serial.println("The effective value of the current is(in mA)");
Serial.println(effective_value,1);
}
void pins_init()
{
pinMode(CURRENT_SENSOR, INPUT);
}
/*Function: Sample for 1000ms and get the maximum value from the S pin*/
int getMaxValue()
{
int sensorValue; //value read from the sensor
int sensorMax = 0;
uint32_t start_time = millis();
while((millis()-start_time) < 1000)//sample for 1000ms
{
sensorValue = analogRead(CURRENT_SENSOR);
if (sensorValue > sensorMax)
{
/*record the maximum sensor value*/
sensorMax = sensorValue;
}
}
return sensorMax;
}
Код: Выделить всё
#define MY_DEBUG // *** Вывод отладочной информации в сериал
#define MY_RADIO_NRF24 // *** Радио
//#define MY_NODE_ID 1 // *** Номер ноды выдается автоматически
#include <SPI.h> // *** Подключение библиотек
#include <MySensors.h> // ***
#define CURRENT_SENSOR A0 // Аналоговый вход к которому подключен сенсор
#define CHILD_ID_AMPLITUDE 0 // ***Id сенсоры ноды (0-254)
#define CHILD_ID_EFFECTIVE 1 // ***
float amplitude_current; // Амплитудный ток
float old_amplitude_current; // *** Предыдущее значение АТ
float effective_value; // Еффективный ток
float old_effective_value; // *** Предыдущее значение ЕТ
bool Ack0, Ack1, err; // ***
byte count; // ***
MyMessage amplmsg(CHILD_ID_AMPLITUDE, V_CURRENT); // *** Создание контейнеров
MyMessage effmsg(CHILD_ID_EFFECTIVE, V_CURRENT); // *** для хранения информации
void setup()
{
pins_init();
}
void presentation() { // *** Презентация сенсоров на контроллере
sendSketchInfo("GY712", "1.0");
wait(20);
present(CHILD_ID_AMPLITUDE, S_MULTIMETER, "Amplitude");
wait(20);
present(CHILD_ID_EFFECTIVE, S_MULTIMETER, "Effective");
}
void loop()
{
int sensor_max;
sensor_max = getMaxValue();
Serial.print("sensor_max = ");
Serial.println(sensor_max);
//the VCC on the Grove interface of the sensor is 5v
amplitude_current=(float)(sensor_max-512)/1024*5/185*1000000; // Для 5А (5/185), для 20А (20/100), для 30А (30/66)
effective_value=amplitude_current/1.414;
// Минимальный ток=1/1024*5/185*1000000/1.414=18.7(mA)
// Только для синусоидального переменного тока
Serial.println("The amplitude of the current is(in mA)");
Serial.println(amplitude_current,1);//Only one number after the decimal point
Serial.println("The effective value of the current is(in mA)");
Serial.println(effective_value,1);
// **********************************************************************************************************************************************************
if(amplitude_current != old_amplitude_current){ // Если значение амплитудного тока изменилось
send(amplmsg.setDestination(0).setSensor(CHILD_ID_AMPLITUDE).set((amplitude_current),1), true); // Отправка его данных c подтверждением доставки на контроллер
wait(50, 1, V_CURRENT); // Ждём подтверждения отправки
wait(500, 1, V_CURRENT); // Ждём подтверждения доставки
while (Ack0 == 0) { // Пока статус доставки ложь
count++; // Включаем счётчик повторных отправок
Serial.print("Sending a message, try No."); // Выводим в монитор порта попытку отправки
Serial.println(count); // и её номер
send(amplmsg.setDestination(0).setSensor(CHILD_ID_AMPLITUDE).set((amplitude_current),1), true); // Отправляем сообщение повторно
wait(50, 1, V_CURRENT); // Ждём подтверждения отправки
wait(1000, 1, V_CURRENT); // Ждём подтверждения доставки
if (count == 3){ // Если сделано 3 попытки
err = 1; // Устанавливаем флаг ошибки
count = 0; // Обнуляем счётчик
Ack0 = 1; // Выходим из цикла
}
}
if ((Ack0 == 1) && (err == 1)){ // Если выражение истина
Serial.println("Delivery failed"); // Выводим сообщение "Доставка не удалась"
Ack0 = 0; // Сбрасываем флаг доставки
err = 0; // И ошибки
} else if ((Ack0 == 1) && (err == 0 )){ // Иначе если выражение истина
Serial.println("Message sent and delivered"); // Вывести в сериал "Сообщение отправлено и доставлено"
Ack0 = 0; // Сбрасываем флаг
count = 0; // Обнуляем счётчик
old_amplitude_current = amplitude_current; // Обновляем предыдущее значение
}
}
if(effective_value != old_effective_value){ // Если значение еффективного тока изменилось
send(effmsg.setDestination(0).setSensor(CHILD_ID_EFFECTIVE).set((effective_value),1), true); // Отправка еффективного тока c подтверждением на контроллер
wait(50, 1, V_CURRENT); // Ждём подтверждения отправки
wait(500, 1, V_CURRENT); // Ждём подтверждения доставки
while (Ack1 == 0) { // Пока статус доставки ложь
count++; // Включаем счётчик повторных отправок
Serial.print("Sending a message, try No."); // Выводим в монитор порта попытку отправки
Serial.println(count); // и её номер
send(effmsg.setDestination(0).setSensor(CHILD_ID_EFFECTIVE).set((effective_value),1), true); // Отправляем сообщение повторно
wait(50, 1, V_CURRENT); // Ждём подтверждения отправки
wait(1000, 1, V_CURRENT); // Ждём подтверждения доставки
if (count == 3){ // Если сделано 3 попытки
err = 1; // Устанавливаем флаг ошибки
count = 0; // Обнуляем счётчик
Ack1 = 1; // Выходим из цикла
}
}
if ((Ack1 == 1) && (err == 1)){ // Если выражение истина
Serial.println("Delivery failed"); // Выводим сообщение "Доставка не удалась"
Ack1 = 0; // Сбрасываем флаг доставки
err = 0; // И ошибки
} else if ((Ack1 == 1) && (err == 0 )){ // Иначе если выражение истина
Serial.println("Message sent and delivered"); // Вывести в сериал "Сообщение отправлено и доставлено"
Ack1 = 0; // Сбрасываем флаг
count = 0; // Обнуляем счётчик
old_effective_value = effective_value; // Обновляем предыдущее значение
}
}
}
void receive(const MyMessage &message) // Функция обработки входящих сообщений
{
if ((message.sender == 0)&&(message.sensor == CHILD_ID_AMPLITUDE)&&(message.isAck())){
Ack0 = 1;
}
if ((message.sender == 0)&&(message.sensor == CHILD_ID_EFFECTIVE)&&(message.isAck())){
Ack1 = 1;
}
}
//****************************************************************************************************************************
void pins_init()
{
pinMode(CURRENT_SENSOR, INPUT);
}
/*Function: Sample for 1000ms and get the maximum value from the S pin*/
int getMaxValue()
{
int sensorValue; //value read from the sensor
int sensorMax = 0;
uint32_t start_time = millis();
while((millis()-start_time) < 1000)//sample for 1000ms
{
sensorValue = analogRead(CURRENT_SENSOR);
if (sensorValue > sensorMax)
{
/*record the maximum sensor value*/
sensorMax = sensorValue;
}
}
return sensorMax;
}