POWER MONITOR на Arduino

Подключение исполнительных устройств, датчиков, контроллеров.

Модератор: immortal

serghei
Сообщения: 2575
Зарегистрирован: Пт ноя 06, 2015 10:22 am
Откуда: Кишинёв
Благодарил (а): 303 раза
Поблагодарили: 282 раза

Re: POWER MONITOR на Arduino

Сообщение serghei » Пт фев 12, 2016 3:28 pm

pastry777 писал(а):кстати да,я положил функции расчета напряжения и тока на ардуино про мини и передаю уже по i2c на мегу.
А как Вы организовали передачу? У меня нана 3 не работает через usb а задача передать 4 мощности и температуру на мегу.
AMS : ESP32 + NRF24 + 1Wire-I2C мост DS2482 + счетчик DS2423 + сеть MySensors + редактирование страниц в браузере + Upload по воздуху + SPIFFS
Аватара пользователя
Kod.Begemot
Сообщения: 358
Зарегистрирован: Чт июн 20, 2013 5:53 pm
Благодарил (а): 32 раза
Поблагодарили: 42 раза

Re: POWER MONITOR на Arduino

Сообщение Kod.Begemot » Пт фев 12, 2016 5:10 pm

Да, кстати, мне тоже интересно как реализовать.
pastry777
Сообщения: 81
Зарегистрирован: Пт окт 02, 2015 7:47 pm
Благодарил (а): 7 раз
Поблагодарили: 4 раза

Re: POWER MONITOR на Arduino

Сообщение pastry777 » Пт фев 12, 2016 8:01 pm

по шине i2c...мега-мастер,мини-слейв...
раз в секунду мастер спрашивает у слейва инфу,тот ей отвечает,соответственно....слейвов может быть много,у каждого свой адрес...
перерыл много примеров,в итоге есть такие нюансы:
1.очень сложны и заморочены способы передачи именно int,float и тд,все что больше одного байта=)
гораздо проще передать строку...поэтому перед отправкой я все float умножаю на сто,чтоб число было целым,далее формирую строку из всех моих значений(у меня их 4) и отправляю мастеру...на мастере получаю эту строку и в обратном порядке парсю(разбираю) ее на int,ну а чтоб привести нужные int в float просто вновь делю на 100...
2.мастер при запросе ожидает конкретное количевство байт и если строка будет меньше чем ожидаемое количество,то мы получим мусор в конце строки,что помешает нам ее правильно разобрать..поэтому на слейве перед отправкой я написал цикл,который проверяет на количество символов получившуюся строку,а оставшиеся заполняет пробелами...так вышел из ситуации я...

тем не менее у меня все работает=)

если кому это действительно необходимо и не получается понять или еще что,маякуйте,посижу пропишу коментарии и выложу пример тогда уже,как получилось у меня...
pastry777
Сообщения: 81
Зарегистрирован: Пт окт 02, 2015 7:47 pm
Благодарил (а): 7 раз
Поблагодарили: 4 раза

Re: POWER MONITOR на Arduino

Сообщение pastry777 » Пт фев 12, 2016 8:07 pm

возможно,что по сериал это было бы проще сделать,но это нужно было бы использовать SoftwareSerial,чтоб не занимать сериал-порт и общаться можно было бы только с одним устройством...поэтому я посидел денек и уже на перспективу организовал передачу по i2c...пока так...
Аватара пользователя
Kod.Begemot
Сообщения: 358
Зарегистрирован: Чт июн 20, 2013 5:53 pm
Благодарил (а): 32 раза
Поблагодарили: 42 раза

Re: POWER MONITOR на Arduino

Сообщение Kod.Begemot » Пт фев 12, 2016 8:23 pm

Буду очень благодарен за код :)
Сейчас МегаД начинает работать с i2c, а у меня на мегах практически всё. Было бы шикарно иметь возможность снимать данные по электропитанию при помощи меги, да по i2c, да ещё и несколько...
Опыта в программировании мало, времени мало, но убедился для себя что разбор хорошего примера может дать очень много :)
pastry777
Сообщения: 81
Зарегистрирован: Пт окт 02, 2015 7:47 pm
Благодарил (а): 7 раз
Поблагодарили: 4 раза

Re: POWER MONITOR на Arduino

Сообщение pastry777 » Пт фев 12, 2016 8:33 pm

ок,сейчас уже пишу...выложу код для пары мастер-слейв,на котором я все это отработал и научился.загрузив их вы наглядно все увидите..а после,уверен,подкорректировав пример вы легко внедрите его в свой код...
pastry777
Сообщения: 81
Зарегистрирован: Пт окт 02, 2015 7:47 pm
Благодарил (а): 7 раз
Поблагодарили: 4 раза

Re: POWER MONITOR на Arduino

Сообщение pastry777 » Пт фев 12, 2016 10:10 pm

и так,код для мастера,основного устройства...
СпойлерПоказать

Код: Выделить всё

#include <Wire.h>

//нужно посчитать макс.длину символов своих передаваемых от слейва данных,считая пробелы между значениями и +1 минимум,можно больше
//я планировал принимать строку вида "1234 220 230 240",поэтому получилось 17
const int symbol = 17;   // получившееся значение

char str[symbol];        // создаем строку,которую будем наполнять получаемыми байтами

int count = 0; //для счетчика в цикле
float Irms;  // переменная для мощности
int volt_vhod, volt_vhod_2, volt_stab; // переменные для напряжения

void setup()
{
  Wire.begin();        // запуск шины i2c,в скобках пусто,означает что мы "мастер"
  Serial.begin(9600);  
}

void loop()
{
  Wire.requestFrom(10, symbol);     // отправляем запрос устройству с адресом 10 и ждем от него наше количество байт
  Serial.print("recieve string: "); // для отладки,вывожу в сериал,что за строку мы получили
  while (Wire.available())          // если есть доступные для чтения данные из шины
  {
    char c = Wire.read(); // читаем символ
    str[count]=c;         // вписываем его в соответствующую ячейку строки
    count++;              // увеличиваем счетчик
    Serial.print(c);      // этот же символ выводим в сериал
  }
  Serial.println();
  count = 0;               // когда данные уже закончились,обнуляем счетчик
  str[symbol-1]='\0';      // в последнюю ячейку ставим символ окончания строки
  
  // разбиваем строку по пробелам и сразу переводим к значениям
  Irms = atoi(strtok(str, " "))/100.0; // функция strtok(str, " "); вернет нам первый набор пока еще символов из нашей строки str до первого пробела,
  // функция atoi приводит набор символов к числу,которое я делю еще на 100,сами знаете зачем=)
  volt_vhod = atoi(strtok(NULL, " ")); // берем вторую группу символов и тд
  volt_vhod_2 = atoi(strtok(NULL, " "));
  volt_stab = atoi(strtok(NULL, " "));
  // кому не ясно,читайте как работает strtok

  // для отладки смотрю уже "разобранную" строку на параметры и их значения
  Serial.print("Irms: ");  Serial.print(Irms);   Serial.print("   ");
  Serial.print("vhod: ");  Serial.print(volt_vhod);   Serial.print("   ");
  Serial.print("vhod_2: ");  Serial.print(volt_vhod_2);   Serial.print("   ");
  Serial.print("stab: ");  Serial.print(volt_stab);   Serial.println();

  delay(1000);
}
 
За это сообщение автора pastry777 поблагодарил:
Serega66 (Ср авг 23, 2017 6:55 pm)
Рейтинг: 1.16%
pastry777
Сообщения: 81
Зарегистрирован: Пт окт 02, 2015 7:47 pm
Благодарил (а): 7 раз
Поблагодарили: 4 раза

Re: POWER MONITOR на Arduino

Сообщение pastry777 » Пт фев 12, 2016 10:11 pm

код для слейв-устройства...
СпойлерПоказать

Код: Выделить всё

////////////////////////////////////////////////
//    СКЕТЧ SLAVE-УСТРОЙСТВА
////////////////////////////////////////////////

#include <Wire.h>

#define SLAVE_i2c_ADRESS 10 // адрес нашего устройства

const int symbol = 17; // должно совпадать с тем,что и в мастере

// здесь наши значения,которые мы будем передавать для примера ///////////////////////////////////////
float Irms = 1.23;     // 1.23кВт
int volt_vhod = 245;   // 245 вольт
int volt_vhod_2 = 235;
int volt_stab = 220;
///////////////////////////////////////////////////////////////////////////////////////////////////////


void setup()
{
    Serial.begin(9600);

    Wire.begin(SLAVE_i2c_ADRESS); // запускаем шину и указываем адрес под каким мы будем

    Wire.onRequest(requestEvent); // тут указывается функция,которая будет выполняться при получении нами запроса от мастера

}

void loop()
{

}

void requestEvent()
{
// создаем временные строки,в которые будем вписывать наши значения
    char str_volt_vhod[4];    //длина напряжения+1 (245-3символа,+1=4)
    char str_volt_vhod_2[4];
    char str_volt_stab[4];
    char str_Irms[5];         // ток может быть 99.99кВт,умножим на 100 когда,получим 4 символа,ну и +1
    char str_to_send[symbol] = { '\0' }; // собственно строка для отправки

// заполняем наши временные строки символами,читайте про itoa...
    // itoa(наше значение int, строка в которую его вписываем, система исчисления(в нашем случае всегда 10));
    itoa(Irms * 100, str_Irms, 10); 
    itoa(volt_vhod, str_volt_vhod, 10);
    itoa(volt_vhod_2, str_volt_vhod_2, 10);
    itoa(volt_stab, str_volt_stab, 10);

// склеиваем строки в одну
// strcat(строка назначения, строка которую приписываем);
    strcat(str_to_send, str_Irms);
    strcat(str_to_send, " ");          // приписываем пробел
    strcat(str_to_send, str_volt_vhod);
    strcat(str_to_send, " ");
    strcat(str_to_send, str_volt_vhod_2);
    strcat(str_to_send, " ");
    strcat(str_to_send, str_volt_stab);

        Serial.println("string to send: " + String(str_to_send)); // для отладки,смотрю,что в итоге мы наклеили=)
    
    int count = strlen(str_to_send); // получаю длину образовавшейся строки
    if (count < symbol) {            // если она меньше чем должна быть,оставшиеся символы в конце набиваю пробелами
        for (int i = count; i < symbol; i++) {
            str_to_send[i] = ' ';
        }
    }
    
    Wire.write(str_to_send); // собственно отправляем строку мастеру
}

 
За это сообщение автора pastry777 поблагодарил:
Serega66 (Ср авг 23, 2017 6:55 pm)
Рейтинг: 1.16%
pastry777
Сообщения: 81
Зарегистрирован: Пт окт 02, 2015 7:47 pm
Благодарил (а): 7 раз
Поблагодарили: 4 раза

Re: POWER MONITOR на Arduino

Сообщение pastry777 » Пт фев 12, 2016 10:19 pm

эта пара,само-собой только что мной опробована,так что загружайте и разбирайтесь...
соединение устройств по трем проводам,SDA к SDA,SCL к SCL и земля общая должна быть..
на UNO,mini,nano: SDA-A4,SCL-A5
на Mega : SDA-20,SCL-21

единственное еще что,так это я не пробовал работать с несколькими слейвами,так что пока не подскажу...
возможно все обойдется просто раздачей разных адресов и запроса к конкретному адресу...это в идеале так и должно быть,на то оно и i2c шина...я пока не пробовал,нет надобности..
За это сообщение автора pastry777 поблагодарил:
Serega66 (Ср авг 23, 2017 6:55 pm)
Рейтинг: 1.16%
pastry777
Сообщения: 81
Зарегистрирован: Пт окт 02, 2015 7:47 pm
Благодарил (а): 7 раз
Поблагодарили: 4 раза

Re: POWER MONITOR на Arduino

Сообщение pastry777 » Пт фев 12, 2016 10:52 pm

короче,ребята,это гениально!!=))все сработало!любопытство победило и я присоединил второй слейв...просто назначил ему другой адрес,ну и с мастера обращался по очереди сначала к одному,потом ко второму и получал значения и с одного и со второго))мелочь,а приятно...
Ответить