Страница 13 из 14
Re: Мои проекты на Ардуино
Добавлено: 19 фев 2015, 20:38
Kopyloff
Т.е. чтобы получить данные неусредненные - нужно указывать диапазон максимум 60 секунд?
Код: Выделить всё
rrdtool fetch /home/base/rrd_currents.rrd AVERAGE --start -1minute
->
неусреднённые данные
А если укажу диапазон больше 1 минуты - то получу усреднённые данные из часовой базы?
Код: Выделить всё
rrdtool fetch /home/base/rrd_currents.rrd AVERAGE --start -61s
->
усреднённые данные
Re: Мои проекты на Ардуино
Добавлено: 19 фев 2015, 20:46
Kopyloff
Щас проверил свои предположения - всё верно, только один нюанс - если указывать
, ни больше ни меньше, то иногда получаю 60 данных посекундно + 2 секунды неопределённых данных (nan), а иногда получаю только 2 значения (как и должно быть)
Re: Мои проекты на Ардуино
Добавлено: 20 фев 2015, 00:16
Serg
Kopyloff писал(а):Т.е. чтобы получить данные неусредненные - нужно указывать диапазон максимум 60 секунд?
Да, ну или увеличить длину этого архива.
Kopyloff писал(а):, ни больше ни меньше, то иногда получаю 60 данных посекундно + 2 секунды неопределённых данных (nan), а иногда получаю только 2 значения (как и должно быть)
Так и должно быть, в самом архиве как-бы свои часы тикают, а твой запрос попадает как-бы в промежуток между квантами времени. Чтобы этого избежать нужно создавать архивы с перекрывающимися диапазонами.
P.S. При работе с RRD приходится соображать и в 4-ом измерении...

Re: Мои проекты на Ардуино
Добавлено: 23 фев 2015, 21:47
Kopyloff
Чёт не могу допетрить - где в программе ошибка.
Было вот так:
Kopyloff писал(а):C Ардуины гадость валится, буду разбираться - почему так.
Начал разбираться с программой - сначала все циклы убрал - думал может во время прерываний с регистрами чего творится - не помогло. Начал проверять по одному все аналоговые входа - оказалось что только на одном аналоговом входе (А0) такие всплески появляются. Ну думаю - значит с этим входом чего-то неладное. Решил просто сдвинуть все входа на 1 и убрать в программе обработку А0. Сделал, загрузил скетч - эти всплески стали появляться на входе А1!!! Т.е. всплески появляются на первом обрабатываемом аналоговом входе. Пока сделал следующее: оставил в программе обработку А0, но на нём фактически ничего не висит - все измерения начинаются с А1. Может у кого мысли есть по данному поводу?
Код: Выделить всё
#include <TimerOne.h> //использует Timer1
#include <SimpleModbusSlave.h>
//////////////////////// Modbus slave ///////////////////////
// Using the enum instruction allows for an easy method for adding and
// removing registers. Doing it this way saves you #defining the size
// of your slaves register array each time you want to add more registers
// and at a glimpse informs you of your slaves register layout.
//////////////// registers of your slave ///////////////////
enum
{
// just add or remove registers and your good to go...
// The first register starts at address 0
mb_A0,
mb_A1,
mb_A2,
mb_A3,
mb_A4,
mb_A5,
mb_A6,
mb_A7,
mb_A8,
mb_A9,
mb_A10,
mb_A11,
mb_A12,
mb_A13,
mb_A14,
mb_A15,
HOLDING_REGS_SIZE // leave this one
// total number of registers for function 3 and 16 share the same register array
// i.e. the same address space
};
unsigned int holdingRegs[HOLDING_REGS_SIZE]; // function 3 and 16 register array
////////////////////////////////////////////////////////////
//================================================================
// http://habrahabr.ru/post/141442/
#define FASTADC 1
// defines for setting and clearing register bits
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
//================================================================
const int k=100;
int cycles=15; // Кол-во обрабатываемых аналоговых входов
int ai_count=cycles, ai_mid_cnt=cycles; // Счетчики циклов 'for'
volatile long Counter=0; // счетчик периодов
volatile int CurA[16]; // Ток текущий
volatile int A[16]; // Аналоговый вход
volatile int CurMaxA[16]; // Ток маскимальный
volatile int CurMinA[16]; // Ток минимальный
volatile long CurMaxCalcA[16]; // Ток маскимальный за весь период
volatile long CurMinCalcA[16]; // Ток минимальный за весь период
float CurMidCalcA[16]; // Ток средний (среднеквадратичное от CurA0calcMax и CurA0calcMin)
volatile int c, v;
// ---------------------
float Current_A[16];
void setup()
{
// Serial.begin(57600);//поднимаем соединение для передачи на терминал
////////////////////// Modbus slave ///////////////////////
modbus_configure(&Serial, 57600, SERIAL_8N1, 1, 2, HOLDING_REGS_SIZE, holdingRegs);
//////////////////////////////////////////////////////////
//================================================================
// http://habrahabr.ru/post/141442/
#if FASTADC
// set prescale to 16
sbi(ADCSRA,ADPS2) ;
cbi(ADCSRA,ADPS1) ;
cbi(ADCSRA,ADPS0) ;
#endif
//================================================================
Timer1.initialize(400); // Интервал срабатывания таймера в мкс
Timer1.attachInterrupt(current_meter); //будет вызываться каждый раз при отсчете заданного времени
}
//********************обработчики прерываний*******************************
void current_meter() //прерывания таймера
{
Counter++; //счетчик периодов
// for (ai_count=0; ai_count < cycles; ai_count++)
// {
// CurA[ai_count] = analogRead(A[ai_count])-512;
// CurMaxA[ai_count] = max(CurA[ai_count],CurMaxA[ai_count]);
// CurMinA[ai_count] = min(CurA[ai_count],CurMinA[ai_count]);
// }
CurA[0] = analogRead(A0)-512;
CurMaxA[0] = max(CurA[0],CurMaxA[0]);
CurMinA[0] = min(CurA[0],CurMinA[0]);
CurA[1] = analogRead(A1)-512;
CurMaxA[1] = max(CurA[1],CurMaxA[1]);
CurMinA[1] = min(CurA[1],CurMinA[1]);
CurA[2] = analogRead(A2)-512;
CurMaxA[2] = max(CurA[2],CurMaxA[2]);
CurMinA[2] = min(CurA[2],CurMinA[2]);
CurA[3] = analogRead(A3)-512;
CurMaxA[3] = max(CurA[3],CurMaxA[3]);
CurMinA[3] = min(CurA[3],CurMinA[3]);
CurA[4] = analogRead(A4)-512;
CurMaxA[4] = max(CurA[4],CurMaxA[4]);
CurMinA[4] = min(CurA[4],CurMinA[4]);
CurA[5] = analogRead(A5)-512;
CurMaxA[5] = max(CurA[5],CurMaxA[5]);
CurMinA[5] = min(CurA[5],CurMinA[5]);
CurA[6] = analogRead(A6)-512;
CurMaxA[6] = max(CurA[6],CurMaxA[6]);
CurMinA[6] = min(CurA[6],CurMinA[6]);
CurA[7] = analogRead(A7)-512;
CurMaxA[7] = max(CurA[7],CurMaxA[7]);
CurMinA[7] = min(CurA[7],CurMinA[7]);
CurA[8] = analogRead(A8)-512;
CurMaxA[8] = max(CurA[8],CurMaxA[8]);
CurMinA[8] = min(CurA[8],CurMinA[8]);
CurA[9] = analogRead(A9)-512;
CurMaxA[9] = max(CurA[9],CurMaxA[9]);
CurMinA[9] = min(CurA[9],CurMinA[9]);
CurA[10] = analogRead(A10)-512;
CurMaxA[10] = max(CurA[10],CurMaxA[10]);
CurMinA[10] = min(CurA[10],CurMinA[10]);
CurA[11] = analogRead(A11)-512;
CurMaxA[11] = max(CurA[11],CurMaxA[11]);
CurMinA[11] = min(CurA[11],CurMinA[11]);
CurA[12] = analogRead(A12)-512;
CurMaxA[12] = max(CurA[12],CurMaxA[12]);
CurMinA[12] = min(CurA[12],CurMinA[12]);
CurA[13] = analogRead(A13)-512;
CurMaxA[13] = max(CurA[13],CurMaxA[13]);
CurMinA[13] = min(CurA[13],CurMinA[13]);
// CurA[14] = analogRead(A14)-512;
// CurMaxA[14] = max(CurA[14],CurMaxA[14]);
// CurMinA[14] = min(CurA[14],CurMinA[14]);
if(Counter==k)
{
Counter=0; //обнуляем счетчик
// for (ai_count=0; ai_count < cycles; ai_count++)
// {
// CurMaxCalcA[ai_count]=CurMaxA[ai_count];
// CurMinCalcA[ai_count]=CurMinA[ai_count];
// CurMaxA[ai_count]=0;
// CurMinA[ai_count]=0;
// }
CurMaxCalcA[0]=CurMaxA[0];
CurMinCalcA[0]=CurMinA[0];
CurMaxA[0]=0;
CurMinA[0]=0;
CurMaxCalcA[1]=CurMaxA[1];
CurMinCalcA[1]=CurMinA[1];
CurMaxA[1]=0;
CurMinA[1]=0;
CurMaxCalcA[2]=CurMaxA[2];
CurMinCalcA[2]=CurMinA[2];
CurMaxA[2]=0;
CurMinA[2]=0;
CurMaxCalcA[3]=CurMaxA[3];
CurMinCalcA[3]=CurMinA[3];
CurMaxA[3]=0;
CurMinA[3]=0;
CurMaxCalcA[4]=CurMaxA[4];
CurMinCalcA[4]=CurMinA[4];
CurMaxA[4]=0;
CurMinA[4]=0;
CurMaxCalcA[5]=CurMaxA[5];
CurMinCalcA[5]=CurMinA[5];
CurMaxA[5]=0;
CurMinA[5]=0;
CurMaxCalcA[6]=CurMaxA[6];
CurMinCalcA[6]=CurMinA[6];
CurMaxA[6]=0;
CurMinA[6]=0;
CurMaxCalcA[7]=CurMaxA[7];
CurMinCalcA[7]=CurMinA[7];
CurMaxA[7]=0;
CurMinA[7]=0;
CurMaxCalcA[8]=CurMaxA[8];
CurMinCalcA[8]=CurMinA[8];
CurMaxA[8]=0;
CurMinA[8]=0;
CurMaxCalcA[9]=CurMaxA[9];
CurMinCalcA[9]=CurMinA[9];
CurMaxA[9]=0;
CurMinA[9]=0;
CurMaxCalcA[10]=CurMaxA[10];
CurMinCalcA[10]=CurMinA[10];
CurMaxA[10]=0;
CurMinA[10]=0;
CurMaxCalcA[11]=CurMaxA[11];
CurMinCalcA[11]=CurMinA[11];
CurMaxA[11]=0;
CurMinA[11]=0;
CurMaxCalcA[12]=CurMaxA[12];
CurMinCalcA[12]=CurMinA[12];
CurMaxA[12]=0;
CurMinA[12]=0;
CurMaxCalcA[13]=CurMaxA[13];
CurMinCalcA[13]=CurMinA[13];
CurMaxA[13]=0;
CurMinA[13]=0;
// CurMaxCalcA[14]=CurMaxA[14];
// CurMinCalcA[14]=CurMinA[14];
// CurMaxA[14]=0;
// CurMinA[14]=0;
}
}
//*************************************************************************
void loop()
{
// for (ai_mid_cnt=0; ai_mid_cnt < cycles; ai_mid_cnt++)
// {
// CurMidCalcA[ai_mid_cnt] = sqrt((sq(CurMaxCalcA[ai_mid_cnt])+sq(CurMinCalcA[ai_mid_cnt]))/2);
CurMidCalcA[0] = sqrt((sq(CurMaxCalcA[0])+sq(CurMinCalcA[0]))/2);
CurMidCalcA[1] = sqrt((sq(CurMaxCalcA[1])+sq(CurMinCalcA[1]))/2);
CurMidCalcA[2] = sqrt((sq(CurMaxCalcA[2])+sq(CurMinCalcA[2]))/2);
CurMidCalcA[3] = sqrt((sq(CurMaxCalcA[3])+sq(CurMinCalcA[3]))/2);
CurMidCalcA[4] = sqrt((sq(CurMaxCalcA[4])+sq(CurMinCalcA[4]))/2);
CurMidCalcA[5] = sqrt((sq(CurMaxCalcA[5])+sq(CurMinCalcA[5]))/2);
CurMidCalcA[6] = sqrt((sq(CurMaxCalcA[6])+sq(CurMinCalcA[6]))/2);
CurMidCalcA[7] = sqrt((sq(CurMaxCalcA[7])+sq(CurMinCalcA[7]))/2);
CurMidCalcA[8] = sqrt((sq(CurMaxCalcA[8])+sq(CurMinCalcA[8]))/2);
CurMidCalcA[9] = sqrt((sq(CurMaxCalcA[9])+sq(CurMinCalcA[9]))/2);
CurMidCalcA[10] = sqrt((sq(CurMaxCalcA[10])+sq(CurMinCalcA[10]))/2);
CurMidCalcA[11] = sqrt((sq(CurMaxCalcA[11])+sq(CurMinCalcA[11]))/2);
CurMidCalcA[12] = sqrt((sq(CurMaxCalcA[12])+sq(CurMinCalcA[12]))/2);
CurMidCalcA[13] = sqrt((sq(CurMaxCalcA[13])+sq(CurMinCalcA[13]))/2);
// CurMidCalcA[14] = sqrt((sq(CurMaxCalcA[14])+sq(CurMinCalcA[14]))/2);
/*
Измеряем максимальный и минимальный пики синусоиды. Затем находим их среднеквадратичное значение.
пик = sqrt( ( (пик мин)^2 + (пик макс)^2 )/2 ) [маш.ед.]
Далее это значение (в машинных единицах - 0-1023) переводим в напряжение:
напряж. = (пик / 1023)*5 [Вольт]
Чувствительность ACS712-20 равна 100 милиВольт/Ампер = 0,1В/А (см. даташит на ACS), отсюда:
ток ампл. = напряж. / Чувствит. = напряж / 0,1 = напряж * 10 [Ампер]
Ток средний - это ток ампл., поделенный на корень из 2:
ток средний = ток ампл. / sqrt(2) = ток ампл. * 0,707 [Ампер]
Итого:
Ток = 0,707*ток ампл. = 0,707 * напряж / чувствит. = 0,707 * напряж. * 10 = 7,07 * напряж. =
= 7,07 * пик * 5 / 1023 = 35,35 * пик / 1023
*/
// Current_A[ai_mid_cnt] = 35.35 * CurMidCalcA[ai_mid_cnt] / 1023.0;
Current_A[0] = 35.35 * CurMidCalcA[0] / 1023.0;
Current_A[1] = 35.35 * CurMidCalcA[1] / 1023.0;
Current_A[2] = 35.35 * CurMidCalcA[2] / 1023.0;
Current_A[3] = 35.35 * CurMidCalcA[3] / 1023.0;
Current_A[4] = 35.35 * CurMidCalcA[4] / 1023.0;
Current_A[5] = 35.35 * CurMidCalcA[5] / 1023.0;
Current_A[6] = 35.35 * CurMidCalcA[6] / 1023.0;
Current_A[7] = 35.35 * CurMidCalcA[7] / 1023.0;
Current_A[8] = 35.35 * CurMidCalcA[8] / 1023.0;
Current_A[9] = 35.35 * CurMidCalcA[9] / 1023.0;
Current_A[10] = 35.35 * CurMidCalcA[10] / 1023.0;
Current_A[11] = 35.35 * CurMidCalcA[11] / 1023.0;
Current_A[12] = 35.35 * CurMidCalcA[12] / 1023.0;
Current_A[13] = 35.35 * CurMidCalcA[13] / 1023.0;
// Current_A[14] = 35.35 * CurMidCalcA[14] / 1023.0;
// }
//////////////////////// Modbus slave ///////////////////////
holdingRegs[mb_A0] = int(Current_A[1]*1000); // update data to be read by the master
holdingRegs[mb_A1] = int(Current_A[2]*1000); // update data to be read by the master
holdingRegs[mb_A2] = int(Current_A[3]*1000); // update data to be read by the master
holdingRegs[mb_A3] = int(Current_A[4]*1000); // update data to be read by the master
holdingRegs[mb_A4] = int(Current_A[5]*1000); // update data to be read by the master
holdingRegs[mb_A5] = int(Current_A[6]*1000); // update data to be read by the master
holdingRegs[mb_A6] = int(Current_A[7]*1000); // update data to be read by the master
holdingRegs[mb_A7] = int(Current_A[8]*1000); // update data to be read by the master
holdingRegs[mb_A8] = int(Current_A[9]*1000); // update data to be read by the master
holdingRegs[mb_A9] = int(Current_A[10]*1000); // update data to be read by the master
holdingRegs[mb_A10] = int(Current_A[11]*1000); // update data to be read by the master
holdingRegs[mb_A11] = int(Current_A[12]*1000); // update data to be read by the master
holdingRegs[mb_A12] = int(Current_A[13]*1000); // update data to be read by the master
// holdingRegs[mb_A13] = int(Current_A[13]*1000); // update data to be read by the master
// holdingRegs[mb_A14] = int(Current_A[14]*1000); // update data to be read by the master
holdingRegs[mb_A15] = int(analogRead(A15)*1000.0*5.0/1023.0); // update data to be read by the master
// holdingRegs[mb_A15] = analogRead(A15); // update data to be read by the master
modbus_update();
////////////////////////////////////////////////////////////
}
Re: Мои проекты на Ардуино
Добавлено: 29 фев 2016, 15:14
releyshic
aftaev писал(а):Написал за пол часика простой осциллограф для Ардуины 2560 с TFT экраном.
Осциллограф чувствительный, но до 5в , но очень медлительный. Весь экран прорисовывается за 15 сек, что не очень быстро

. Если убрать вывод цифровых чисел и передачу данных в СОМ будет шустрее работать шустрее намного, примерно 1-3 сек заполняться экран.
удивительно что он вообще что-то рисует )) с двумя бесконечными циклами без выхода )) фантастика )) правда работает только один цикл ) ещё и ";" после тела функции, компилятор уснул наверное ))
и вообще, зачем городить бесконечный цикл если loop сам по себе бесконечный цикл )
организуй работу по прерываниям по входу analogPin и записывай значение в переменную типа volatill, в самом цикле считывай значение переменной и будет быстро работать
Re: Мои проекты на Ардуино
Добавлено: 29 фев 2016, 15:20
AndyBig
releyshic писал(а):ещё и ";" после тела функции, компилятор уснул наверное ))
Это никогда не считалось ошибкой и вполне допустимо

Re: Мои проекты на Ардуино
Добавлено: 02 мар 2016, 15:38
AndyBig
Почему спамера до сих пор не грохнули?

Re: Мои проекты на Ардуино
Добавлено: 02 мар 2016, 15:47
Сергей Саныч
AndyBig писал(а):Почему спамера до сих пор не грохнули?

потому что треугольную капу некому нажать было

Re: Мои проекты на Ардуино
Добавлено: 30 окт 2016, 14:32
dmbden
Kopyloff писал(а):Подниму-ка старую, но интересную тему
aftaev - с Вашего позволения напишу свой пост здесь, отдельную тему поднимать не вижу смысла. Если против - можете выделить в новую тему.
Итак, предлагаю вашему вниманию новую модель относительно быстрого осциллографа - частота снятия показаний - до 280 микросекунд.
Сразу скажу, что собирать именно осциллограф на ардуино я не собирался, но раз уж попались мне все ингредиенты- почему не попробовать?
Хочу собрать систему а-ля "Умный дом". Задача минимум на данный момент - собрать статистику энергопотребления в доме и на её базе автоматизировать управление электроприборами (в автомат. режиме или удалённо, через веб-морду). Ну - это в обозримом будущем. Не о том сейчас.
Вот эти ингредиенты:
- ардуино мега 2560
- TFT LCD экранчик, 2.4", на контроллере st7783:
2015-02-02 17.52.02.jpg
- датчик тока на элементе ACS712-20А (вот тут брал:
http://www.ebay.com/itm/1pcs-new-20A-ra ... 51c48706bb)
Ну и для тестов - нагрузка в виде утюга и автомобильного зарядного с аккумулятором
Получился такой вот код:
Код: Выделить всё
#include <Adafruit_GFX.h> // Core graphics library
#include "SWTFT.h" // Hardware-specific library
#include <TimerOne.h> //используем Timer1 для прерываний по времени
// Assign human-readable names to some common 16-bit color values:
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define DARKRED 0x2020
#define GREEN 0x07E0
#define DARKGREEN 0x2121
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
SWTFT tft;
int ACS712 = A8; // select the input pin for an ACS712-20
int Uopornoe;// = A15; // select the input pin for a reference voltage
const int k=160; // k - кол-во записей в массив.
const int numReadings = 30; // numReadings - кол-во данных в фильтре.
boolean trig, resize;
volatile long PintTic=0; // счетчик периодов
volatile int CurA0; // Ток текущий
volatile int CurA0max; // Ток маскимальный
volatile long CurA0calcMax; // Ток маскимальный за весь период
volatile int CurA0min; // Ток минимальный
volatile long CurA0calcMin; // Ток минимальный за весь период
volatile int ymax=256, ymin=-256; // значения для масштабирования графика и сетки
float CurA0calcMid; // Ток средний (среднеквадратичное от CurA0calcMax и CurA0calcMin)
volatile int val_a[501]; //Массив значений A0 в прерываниях
volatile int val_a2[501]; //Массив значений времени в прерываниях
volatile int val_Uo[501]; //Массив значений опорного напряжения прерываниях
volatile long val_t[501]; //Массив значений времени в прерываниях
volatile int nb[501]; //Массив для учета номера итерации
volatile int i, z, c, v;
int scr_out, x1=0, x2=1, y1=120, y2=120;
// Переменные для фильтра
float readings[numReadings]; // the readings from the analog input
float total = 0; // the running total
float average = 0; // the average
float A0_current;
unsigned long previousMillis = 0; // will store last time LED was updated
const long interval = 6000; // interval at which to blink (milliseconds)
void setup(void) {
Serial.begin(9600); //поднимаем соединение для передачи на терминал
// Инициализация данных в массиве фильтра в 0:
for (int thisReading = 0; thisReading < numReadings; thisReading++)
readings[thisReading] = 0;
tft.reset();
uint16_t identifier = tft.readID();
Serial.print(F("LCD driver chip: "));
Serial.println(identifier, HEX);
tft.begin(identifier);
tft.setRotation(1);
//рисуем сетку
Grid();
// Запуск таймера
Timer1.initialize(400); // Интервал срабатывания таймера в мкс
Timer1.attachInterrupt(current_meter); //будет вызываться каждый раз при отсчете заданного времени
}
void loop(void) {
// Закрашиваем чёрным предыдущее значение тока:
tft.setCursor(96, 4);
tft.setTextColor(BLACK); tft.setTextSize(1);
tft.println(A0_current,2);
tft.setCursor(222, 4);
tft.print(average,2);
unsigned long currentMillis = millis();
if(currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
Grid();
scr_out = 0;
x1=0; x2=1; y1=120,y2=120;
while (scr_out <= k) {
// Ноль координат - в верхнем левом углу экрана!!! Вынос мозга...
y2 = map(val_a2[scr_out], ymin, ymax, 240, 0);
tft.drawLine(x1, y1, x2, y2, GREEN);
x1 = x2;
y1 = y2;
x2 = x2 + (tft.width()/k);
/*
Serial.print(scr_out);//
Serial.print(" , ");//
Serial.print(val_a2[scr_out]);//
Serial.println("");//
*/
scr_out++;
}
// Данный триггер сбросится только после заполнения буфера новыми данными в прерывании current_meter
trig = true;
}
CurA0calcMid = sqrt((sq(CurA0calcMax)+sq(CurA0calcMin))/2);
/*
Измеряем максимальный и минимальный пики синусоиды. Затем находим их среднеквадратичное значение.
пик = sqrt( ( (пик мин)^2 + (пик макс)^2 )/2 ) [маш.ед.]
Далее это значение (в машинных единицах - 0-1023) переводим в напряжение:
напряж. = (пик / 1023)*5 [Вольт]
Чувствительность ACS712-20 равна 100 милиВольт/Ампер = 0,1В/А (см. даташит на ACS), отсюда:
ток ампл. = напряж. / Чувствит. = напряж / 0,1 = напряж * 10 [Ампер]
Ток средний - это ток ампл., поделенный на корень из 2:
ток средний = ток ампл. / sqrt(2) = ток ампл. * 0,707 [Ампер]
Итого:
Ток = 0,707*ток ампл. = 0,707 * напряж / чувствит. = 0,707 * напряж. * 10 = 7,07 * напряж. =
= 7,07 * пик * 5 / 1023 = 35,35 * пик / 1023
*/
A0_current = 35.35 * CurA0calcMid / 1023.0;
//=================== Фильтр сглаживающий: ================
// передвигаем данные в массиве:
v = numReadings;
while (v > 0) {
readings[v]=readings[v-1];
v--;
}
readings[0] = A0_current;
// Serial.print("A0_current = "); Serial.print(A0_current); Serial.print(" ; ");
c = 0;
total = 0;
while (c < numReadings) {
total += readings[c];
// Serial.print(readings[c]); Serial.print(" ; ");
// Serial.print(total); Serial.println("");
c++;
}
// calculate the average:
average = total / numReadings;
// ======================================================
// Выводим на экран значение тока:
tft.setCursor(60, 4);
tft.setTextColor(WHITE); tft.setTextSize(1);
tft.print("Iact= "); tft.print(A0_current,2); tft.print(" A");
// Среднее значение тока (после фильтра)
tft.setCursor(180, 4);
tft.print("Iaver= "); tft.print(average,2); tft.print(" A");
// Serial.print("Free memory size: "); // печать количества свободной оперативной памяти
// Serial.println(memoryFree()); // печать количества свободной оперативной памяти
}
//********************обработчики прерываний*******************************
void current_meter() //прерывания таймера
{
PintTic++; //счетчик периодов
Uopornoe = analogRead(A15);
CurA0 = analogRead(ACS712)-(Uopornoe/2);
CurA0max = max(CurA0,CurA0max);
CurA0min = min(CurA0,CurA0min);
val_a[PintTic] = CurA0;
// val_Uo[PintTic] = Uopornoe;
// nb[PintTic] = PintTic;
// val_t[PintTic] = micros();
if(PintTic==k)
{
if (trig == true) {
z = 0;
while (z <= k) { val_a2[z] = val_a[z]; z++; }
// ymax = CurA0max; ymin = CurA0min; // Сохраняем макс. и мин. значения в массиве
}
trig = false;
PintTic=0; //обнуляем счетчик
CurA0calcMax=CurA0max;
CurA0calcMin=CurA0min;
CurA0max=0;
CurA0min=0;
}
}
//*************************************************************************
void Grid()
{
tft.fillScreen(BLACK);
// tft.drawLine(x1, y1, x2, y2, color);
// Ноль координат - в верхнем левом углу экрана!!! Вынос мозга...
tft.drawLine(0, 0, 0, 240, BLUE); // Ось ординат
// 120*75%=90.
tft.drawLine(0, (120-(90*(1024/(ymax-ymin)))), 319, (120-(90*(1024/(ymax-ymin)))), DARKGREEN); // 75%
// 120*50%=60.
tft.drawLine(0, (120-(60*(1024/(ymax-ymin)))), 319, (120-(60*(1024/(ymax-ymin)))), DARKGREEN); // 50%
// 120*25%=30.
tft.drawLine(0, (120-(30*(1024/(ymax-ymin)))), 319, (120-(30*(1024/(ymax-ymin)))), DARKGREEN); // 25%
// В пикселях по оси Y: 240/2=120 пикселей - это середина экрана.
tft.drawLine(0,120,319,120, BLUE); // Ноль
// 120 пикселей - это 100% сигнала. 120*25%=30.
tft.drawLine(0, (120+(30*(1024/(ymax-ymin)))), 319, (120+(30*(1024/(ymax-ymin)))), DARKGREEN); // -25%
// 120 пикселей - это 100% сигнала. 120*50%=60.
tft.drawLine(0, (120+(60*(1024/(ymax-ymin)))), 319, (120+(60*(1024/(ymax-ymin)))), DARKGREEN); // -50%
// 120 пикселей - это 100% сигнала. 120*75%=90.
tft.drawLine(0, (120+(90*(1024/(ymax-ymin)))), 319, (120+(90*(1024/(ymax-ymin)))), DARKGREEN); // -75%
}
// Переменные, создаваемые процессом сборки,
// когда компилируется скетч
// extern int __bss_end;
// extern void *__brkval;
/*
// Функция, возвращающая количество свободного ОЗУ (RAM)
int memoryFree()
{
int freeValue;
if((int)__brkval == 0)
freeValue = ((int)&freeValue) - ((int)&__bss_end);
else
freeValue = ((int)&freeValue) - ((int)__brkval);
return freeValue;
}
*/
Собирался использовать тачскрин - сделать кнопки для обновления и для масштабирования графика по высоте, но тачскрин не захотел работать в том же чипе, что и прерывание по таймеру TimerOne. Точнее - если делать прерывание больше 1000 микросекунд - тогда тач начинает кое-как работать, но тут уже лучше кнопками пожертвовать, чем частотой измерений.
Ну и фото того что получилось:
2015-02-04 20.46.32.jpg
Сначала в качестве нагрузки - утюг:
2015-02-04 20.54.59.jpg
2015-02-04 20.55.13.jpg
Где-то читал, что современные импульсные блоки питания (компы и прочая бытовая техника) срезают верхушку синусоиды. Здесь на маленьком экранчике не очень хорошо видно, а в экселе когда график строишь из полученных данных - видно срезанную верхушку.
Далее в качестве нагрузки - автомобильное зарядное с аккумулятором:
2015-02-04 21.05.07.jpg
2015-02-04 21.06.08.jpg
2015-02-04 21.07.05.jpg
Почему при компиляции данного скетча появляется ошибка?
Arduino: 1.6.12 (Windows 7), Плата:"Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"
C:\Users\Тема\Documents\Arduino\toknadisplay\toknadisplay.ino: In function 'void setup()':
toknadisplay:76: error: 'Grid' was not declared in this scope
toknadisplay:80: error: 'current_meter' was not declared in this scope
C:\Users\Тема\Documents\Arduino\toknadisplay\toknadisplay.ino: In function 'void loop()':
toknadisplay:98: error: 'Grid' was not declared in this scope
Используем библиотеку Adafruit-GFX-Library-master версии 1.1.5 из папки: C:\Users\Тема\Documents\Arduino\libraries\Adafruit-GFX-Library-master
Используем библиотеку SWTFT-Shield в папке: C:\Users\Тема\Documents\Arduino\libraries\SWTFT-Shield (legacy)
Используем библиотеку TimerOne-master версии 1.1 из папки: C:\Users\Тема\Documents\Arduino\libraries\TimerOne-master
exit status 1
'Grid' was not declared in this scope
Re: Мои проекты на Ардуино
Добавлено: 30 окт 2016, 17:37
Kopyloff
Проблема в версиях Ардуино IDE. Попробуйте "void current_meter {}" и "void Grid() {}" поставить перед "void setup"
Re: Мои проекты на Ардуино
Добавлено: 01 ноя 2016, 19:51
dmbden
Спасибо помогло) Только другие начали ошибки вылазить, их я по исправлял, но теперь пишет что недостаточно памяти и не записывает полностью скетч( Что делать?
Re: Мои проекты на Ардуино
Добавлено: 01 ноя 2016, 20:17
Kopyloff
Странно что не записывает. IDE только предупреждает что памяти в обрез. но должно хватить:
Скетч использует 14 684 байт (5%) памяти устройства. Всего доступно 253 952 байт.
Глобальные переменные используют 6 495 байт (79%) динамической памяти, оставляя 1 697 байт для локальных переменных. Максимум: 8 192 байт.
Недостаточно памяти, программа может работать нестабильно.
У меня сейчас нет Меги свободной, проверить не на чем

Re: Мои проекты на Ардуино
Добавлено: 01 ноя 2016, 20:21
Kopyloff
Как вариант - проверить на старой версии IDE. Там как-то работало

Re: Мои проекты на Ардуино
Добавлено: 02 ноя 2016, 13:56
dmbden
Kopyloff писал(а):Странно что не записывает. IDE только предупреждает что памяти в обрез. но должно хватить:
Скетч использует 14 684 байт (5%) памяти устройства. Всего доступно 253 952 байт.
Глобальные переменные используют 6 495 байт (79%) динамической памяти, оставляя 1 697 байт для локальных переменных. Максимум: 8 192 байт.
Недостаточно памяти, программа может работать нестабильно.
У меня сейчас нет Меги свободной, проверить не на чем

Да, вот это всё появляется, он записывает, но появляется только белый экран и мерцает в придачу, чёртов китайский дисплей, если бы знал об этой фигне не покупал бы

Re: Мои проекты на Ардуино
Добавлено: 02 ноя 2016, 14:20
dmbden
На будущее, если при компиляции появится такая ошибка
(C:\Users\Eraldo\Documents\Arduino\libraries\SWTFT\SWTFT.cpp: In member function 'void SWTFT::drawLine3Byte(int16_t, int16_t, int16_t, int16_t, uint8_t, uint8_t, uint8_t)':
C:\Users\Eraldo\Documents\Arduino\libraries\SWTFT\SWTFT.cpp:629:16: error: 'swap' was not declared in this scope
swap(x0, y0);
^
C:\Users\Eraldo\Documents\Arduino\libraries\SWTFT\SWTFT.cpp:634:16: error: 'swap' was not declared in this scope
swap(x0, x1);
exit status 1
Errore durante la compilazione)
^
Её решение: Вставить вот эту строчку в скобках (#define swap(a, b) { int16_t t = a; a = b; b = t; }) в файл SWTFT.cpp этот фай желательно открывать через WordPad, в обычном текстовом редакторе текст весь в одной строке!
Я вставлял перед строчкой void SWTFT::drawLine3Byte(int16_t x0, int16_t y0,
Re: Мои проекты на Ардуино
Добавлено: 02 ноя 2016, 16:24
dmbden
Я со всем разобрался все проблемы из за библиотек, вот самая рабочая библиотека на этом сайте (
https://robom.ru/blog/displei/sensornyj ... yujma.html) В тестовом режиме запустилось всё, но тач не правильно работает, ну с этим я потом буду разбираться)
Всем спасибо!
Re: Мои проекты на Ардуино
Добавлено: 19 ноя 2017, 23:00
-=KGB_spy=-
Добрый вечер!
Есть ардуино 2560 и дисплей 3,6" для неё, поможете запустить осциллограф?
Тесты я покрутил, дисплей показывает.
Скетч с 7 странички не работает.
Re: Мои проекты на Ардуино
Добавлено: 19 ноя 2017, 23:49
aftaev
Выложи скеч, посмотрим.
-=KGB_spy=- писал(а):Тесты я покрутил, дисплей показывает.
И пример скетча под экран.
Re: Мои проекты на Ардуино
Добавлено: 20 ноя 2017, 00:17
-=KGB_spy=-
kgbyka писал(а):Код: Выделить всё
// библиотека для работы с дисплеем
#include <UTFT.h>
// создаём объект класса UTFT
// и передаём идентификатор модели дисплея и номера управляющих пинов
UTFT myGLCD(CTE32HR, 38, 39, 40, 41);
// объявления встроенного шрифта
extern uint8_t BigFont[];
void setup()
{
// инициализируем дисплей с вертикальной ориентацией
myGLCD.InitLCD();
// очищаем экран
myGLCD.clrScr();
// выбираем большой шрифт
myGLCD.setFont(BigFont);
// устанавливаем красный цвет «чернил» для печати и рисования
myGLCD.setColor(VGA_RED);
// печатаем строку в указанной строке позиции
myGLCD.print("Hello, World!", CENTER, 0);
// устанавливаем синий цвет «чернил» для печати и рисования
myGLCD.setColor(VGA_BLUE);
// печатаем строку в указанной строке позиции
myGLCD.print("Hello, World!", CENTER, 36);
// устанавливаем зелёный цвет «чернил» для печати и рисования
myGLCD.setColor(VGA_GREEN);
// печатаем строку в указанной строке позиции
myGLCD.print("Hello, World!", CENTER, 72);
// устанавливаем серебряный цвет «чернил» для печати и рисования
myGLCD.setColor(VGA_SILVER);
// печатаем строку в указанной строке позиции
myGLCD.print("Hello, World!", CENTER, 108);
}
void loop()
{
}
не работающий попозже выложу.
Re: Мои проекты на Ардуино
Добавлено: 20 ноя 2017, 00:26
aftaev
Берешь мой скетч и там меняешь мой экран UTFT myGLCD(ITDB32S,38,39,40,41); на свой UTFT myGLCD(CTE32HR, 38, 39, 40, 41);