помогите понять смысл куска скетча

lopezmil
Offline
Зарегистрирован: 17.02.2015
Есть вот такой кусок скетча:
 
float getVPP()
{
  float result;
  
int readValue;             //value read from the sensor
  int maxValue = 0;          // store max value here
   uint32_t start_time = millis();
   while((millis()-start_time) < 1000) //sample for 1 Sec
   {
       readValue = analogRead(sensorTA12);
       // see if you have a new maxValue
       if (readValue > maxValue) 
       {
           /*record the maximum sensor value*/
           maxValue = readValue;
       }
   }
   
   // Convert the digital data to a voltage
   result = (maxValue * 5.0)/1024.0;
  
   return result;
 }
 
Правильно ли я понимаю, что здесь происходит вычисление float getVPP() ? И всё, что после этой записи находится  в скобках{} лишь расчёт?
jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

запоминается время затем в течении секунды относительно этого времени измеряется уровень сигнала и запоминается самый большой. затем он (самый большой) пересчитывается и возвращается в основную программу вольтах судя по формуле

NeiroN
NeiroN аватар
Offline
Зарегистрирован: 15.06.2013

Максимальное напряжение на входе sensorTA12 за 1 секунду. Тоесть в течении 1 сек он измеряет находя максимум, потом расчитывает напряжение.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

))) все же в комментариях написано, только сейчас прочитал их))) тс мог бы хоть переводчиком перевести

lopezmil
Offline
Зарегистрирован: 17.02.2015

И хранится это максимальное значение в  float getVPP() ?

lopezmil
Offline
Зарегистрирован: 17.02.2015

Комментарии я перевел и они мне понятны. Но мне ен совсем понятен этот заковыристый язык программирования.

lopezmil
Offline
Зарегистрирован: 17.02.2015

Говоря по-русски, float getVPP() = всё остальное, что замкнуто в скобки после эхтой строки?

lopezmil
Offline
Зарегистрирован: 17.02.2015

Или точнее float getVPP() = float result; а float result; = всё остальное, что ниже   этой строки?

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

что внутри float getVPP() в скобках { в начале и } в конце это кусок программы завернутый в функцию с названием float getVPP(). в программе проще разобраться если разбить на функции, а также есть какой то кусок может повторятся несколько или много раз в коде

функция объявляется (function это название, может быть любым, но оригинальным):

void function() просто функция что то сделает

void function(int i) функция в которую еще передается какой то параметр, исходя из которого функция может по разному работать. параметров может быть несколько

float function() функция которая что то делает и должна вернуть значение. может быть не только float а любой размерности, например byte/ пример millis() если ее вызвать он возвращает количество миллисекунд

float function(int i) тоже самое но в нее еще передается какой то параметр

lopezmil
Offline
Зарегистрирован: 17.02.2015

С функцией float getVPP() более или менее понятно. Она возвращает значение float result. А вот  millis() не совсем понял как и куда она возвращает миллисекунды?

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

time=millis();

millis пересчитывает текущее время и возвращает его значение из функции, затем оно записывается в time. может так понятнее

float getVPP() делает тоже самое. что то делает и возвращает число туда откуда вызывали функцию

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

lopezmil пишет:

Комментарии я перевел и они мне понятны. Но мне ен совсем понятен этот заковыристый язык программирования.

назовите тот, который вам понятен.  ;)

я готов переписать код на понятном вам языке. ;)

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

lopezmil пишет:

С функцией float getVPP() более или менее понятно. Она возвращает значение float result. А вот  millis() не совсем понял как и куда она возвращает миллисекунды?

она наращивается, цикл продолжается пока разница меньше предшествующей миллис одна секунда

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016
 float getVPP() //определяем функцию с именем getVPP, результат вычисления фунции будет в форме десятичной дроби
{
  float result;   //внутренняя переменная с именем result способная хранить десятичные дроби
  
int readValue;             //value read from the sensor
//переменна с именем readValue, способная хнанить только целые числа
  int maxValue = 0;          // store max value here
// переменна с именем maxValue, способная хнанить только целые числа, начальное значение = 0
   uint32_t start_time = millis();
// переменная способная хранить очень большие целые числа, с именем start_time и начальным значение, равным текущему системному времени в миллисекундах 
  while((millis()-start_time) < 1000) //sample for 1 Sec
//пока не пройдет 1000 миллисек делаем то, что написано ниже
   {
       readValue = analogRead(sensorTA12);
//в переменной readValue сохраним значение АЦП кода для аналогового входа с именем sensorTA12
       // see if you have a new maxValue
       if (readValue > maxValue) 
//в переменной maxValue сохраним большее значение из maxValue и  readValue
       {
           /*record the maximum sensor value*/
           maxValue = readValue;
       }
   }
   
   // Convert the digital data to a voltage
   result = (maxValue * 5.0)/1024.0;
// в переменной result сохраним пересчет АЦП - кода, сохраненного в  maxValue, в вольты.
  
   return result;
 }// результатом вычисления функции назначим значение, сохраненное в result

 

Так стало понятнее?

Вы зачем вообще полезли разбирать код, не зная программирования? Мотивация какая? Вам будет очень трудно. Ведь в этой области даже "букварь" для Вас непонятен. Может не стоит оно того?

lopezmil
Offline
Зарегистрирован: 17.02.2015

FBD, если можно.

lopezmil
Offline
Зарегистрирован: 17.02.2015

Я и не особо хочу лезть сюда. Но блок для FBD делается на текстовом языке. Никто тот блок, который мне нужен делать пока не собирается. Поэтому приходится самому, по немногу, с помощью хороших и знающих людей, реализовывать его. Так что извините за мою безграмотность в данном вопросе.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

lopezmil пишет:

Или точнее float getVPP() = float result; а float result; = всё остальное, что ниже   этой строки?

Да, прочтите уже хоть какую-нибудь книжку по языку С, ну сколько ж можно ...

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ЕвгенийП пишет:

lopezmil пишет:

Или точнее float getVPP() = float result; а float result; = всё остальное, что ниже   этой строки?

Да, прочтите уже хоть какую-нибудь книжку по языку С, ну сколько ж можно ...

тут думаю с бэйсика надо начинать )))

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Помнится я на первом курсе сдавал экзамены и один из вопросов был вопрос о различии формальных и фактических параметров функции и я сел в лужу, если не ошибаюсь, получил трояк с натяжкой. Зато на третьем был отмечен оценкой отлично автоматом по программированию :) так что "лиха беда начало". Я не говорю, что из ТС что то получится, просто всяко бывает.

 

lopezmil
Offline
Зарегистрирован: 17.02.2015

Так очень понятно. Премного благодарен!

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

lopezmil пишет:

FBD, если можно.

Выё...ваемся? Некрасиво это...

FBD - не получится, картинки мне не в чем рисовать.

Но текстовый вид - это ST, например. Думаю, что Вам подойдет. Другой раз думать станете, перед тем как пальцы гнуть.

FUNCTION getVPP() : REAL;

VAR
result   : REAL;
readValue: INT;
maxValue : INT;
start_time : DINT;
END_VAR;

start_time := millis();

WHILE millis()-start_time < 1000 DO

 readValue := analogRead(sensorTA12);
 IF readValue > maxValue THEN
    maxValue := readValue;
 END_IF;   
END_WHILE;   

result := (maxValue * 5.0)/1024.0;
getVPP:= result;
RETURN;

END_FUNCTION;

могут быть мелкие ошибки... этой чухней я уже лет 20 не пользовался.

lopezmil
Offline
Зарегистрирован: 17.02.2015

  Чтобы впредь не возникало таких недорозумений, дам всю информацию по этой теме. Я слесарь КИПиА. Работаю наладчиком автоматики. Появилась у меня идея сделать датчик переменного тока для определения работоспособности разного рода эл. моторов и пр. С текстовыми языками у меня туго. Пробовал изучать паскаль, вроде нравится, но времени на это катастрофически не хватает. А тут наткнулся на программу flprog. Там можно программировать ардуину на языке FBD. Этот язык мне более чем знаком. Так как схемы я читаю на отлично. Но среда программирования молодая и функциональных блоков маловато. Необходимого мне тоже не нашлось. Ждать его можно долго. А тут разработчик реализовал возможность создания блоков текстовыми языками. Я решил попробовать. Нашел на просторах интерента скетч для измерительного трансформатора  TA12-100 и на его основе пытаюсь сделать бок на FBD для дальнейшего его использования. Надеюсь теперь всё понятно. А вот исходный код и автор сего творения :

// Henry's Bench TA-1200 AC Current Sensor Tutorial


int sensorTA12 = A0; // Analog input pin that sensor is attached to

float nVPP;   // Voltage measured across resistor
float nCurrThruResistorPP; // Peak Current Measured Through Resistor
float nCurrThruResistorRMS; // RMS current through Resistor
float nCurrentThruWire;     // Actual RMS current in Wire

void setup() 
 {
   Serial.begin(9600); 
   pinMode(sensorTA12, INPUT);
 }
 
 
 void loop() 
 {
   
   
   nVPP = getVPP();
   
   /*
   Use Ohms law to calculate current across resistor
   and express in mA 
   */
   
   nCurrThruResistorPP = (nVPP/200.0) * 1000.0;
   
   /* 
   Use Formula for SINE wave to convert
   to RMS 
   */
   
   nCurrThruResistorRMS = nCurrThruResistorPP * 0.707;
   
   /* 
   Current Transformer Ratio is 1000:1...
   
   Therefore current through 200 ohm resistor
   is multiplied by 1000 to get input current
   */
   
   nCurrentThruWire = nCurrThruResistorRMS * 1000;

   
   Serial.print("Volts Peak : ");
   Serial.println(nVPP,3);
 
   
   Serial.print("Current Through Resistor (Peak) : ");
   Serial.print(nCurrThruResistorPP,3);
   Serial.println(" mA Peak to Peak");
   
   Serial.print("Current Through Resistor (RMS) : ");
   Serial.print(nCurrThruResistorRMS,3);
   Serial.println(" mA RMS");
   
   Serial.print("Current Through Wire : ");
   Serial.print(nCurrentThruWire,3);
   Serial.println(" mA RMS");
   
   Serial.println();
    
   
   

 }


 /************************************ 
In order to calculate RMS current, we need to know
the peak to peak voltage measured at the output across the
200 Ohm Resistor

The following function takes one second worth of samples
and returns the peak value that is measured
 *************************************/
 
 
float getVPP()
{
  float result;
  int readValue;             //value read from the sensor
  int maxValue = 0;          // store max value here
   uint32_t start_time = millis();
   while((millis()-start_time) < 1000) //sample for 1 Sec
   {
       readValue = analogRead(sensorTA12);
       // see if you have a new maxValue
       if (readValue > maxValue) 
       {
           /*record the maximum sensor value*/
           maxValue = readValue;
       }
   }
   
   // Convert the digital data to a voltage
   result = (maxValue * 5.0)/1024.0;
  
   return result;
 }

 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Бедный человек!

Ты в самом деле представляешь себе работу автоматики только в этих адовых картинках?

----

Уж прости, сам рисовать не стану, это непедагогично, но объясню в терминах это жуткой мути - flprog - как тебе нарисовать нужное.

ИТАК:

1. добавляешь аналоговый вход.

2. добавляешь две переменные, одну float, другую int. Float - для результата, int - для промежуточного максимума.

3. millis() в этой поделке недоступна. Как будем поступать? Нет ничего проще! Делаешь генератор на период (тут важно не зырываться, потому, что эта херня ничего не проверяет на реальность) допустим 1 мс или 500 мкс, не меньше. И счетчик.

4. делаешь 1000 измерений, для генератора 1 мс или 2000 для 500 мкс. Тут есть хитрость. Импульс генератора  - он как синхроимпульс для фиксации измерения. Сумеешь такое сам нарисовать?

5. В каждом измерении сравниваешь вход и переменную для максимума и записываешь в нее MAX. Тут понятно?

6. арифметикой вычисляешь из полученного "макса" значение в вольтах и записываешь его в результирующую переменную, или просто на выход отправляешь, смотря, что тебе нужно.

--------------------

еще раз: понятно ли как обойти отсутствие millis() в flProg? Генератором и счетчиком,  таймером не выйдет, тебе импульс EN нужен столько раз, сколько измерений тебе нужно сделать.

------

и еще раз: понятно ли, зачем делать много измерений и искать максимум? Для получения АМПЛИТУДНОГО значения, из которого, потом, можно посчитать действующее.

lopezmil
Offline
Зарегистрирован: 17.02.2015

Синхронный мультивибратор. На вход генератора подается измеряемая величина (датчик тока). В зависимости от мощности сигнала количество импульсов на выходе генератора будет разное. Количество импульсов  считается счётчиком и выдается в виде числа int. Наверное не то. Потому как я не могу понять как отделить разные измерения?

lopezmil
Offline
Зарегистрирован: 17.02.2015

  Не получилось у меня пока. Что значит генератор на период 1мс? И какой выход должен быть у этого генератора, в каких еденицах? 4 пункт тоже боюсь неправильно понял. Как я понимаю в момент импульса генератора должно фиксироватся текущее значение измерения с аналогового входа?  Чем оно должно фиксироватся и куда записыватся? И чем можно сравнить максимальное значение измерения и текущее, чтобы на выходе сравнения получилась int переменная? 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Вот это занимает 100 микросекунд, для нахождения максимума нужно сделать более 200 измерений, у коде их 1000,

это не работает?
 

 readValue = analogRead(sensorTA12);

 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

ТС нужно все нарисовать в FBD, он не умеет программировать иначе.

lopezmil
Offline
Зарегистрирован: 17.02.2015

Проверьте пожалуйста, всё ли в этом коде правильно?

 

int sensorTA12 = A0; 
 float nVPP;                
float nCurrThruResistorPP;
float nCurrThruResistorRMS;
float nCurrentThruWire;    

void setup() 
 {
   Serial.begin(9600); 
   pinMode(sensorTA12, INPUT);
 } 
 
 void loop() 
 {      
  float result;  
  int readValue;           
  int maxValue = 0;         
   uint32_t start_time = millis();
   while((millis()-start_time) < 1000) 
   {
       readValue = analogRead(sensorTA12);
       
       if (readValue > maxValue) 
       {           
           maxValue = readValue;
       }
   }   
  
   result = (maxValue * 5.0)/1024.0;

   nCurrThruResistorPP = (result/200.0) * 1000.0;   
   
   nCurrThruResistorRMS = nCurrThruResistorPP * 0.707;   
   
   nCurrentThruWire = nCurrThruResistorRMS * 1000;   
   
   Serial.print("Current Through Wire : ");
   Serial.print(nCurrentThruWire,3);
   Serial.println(" mA RMS");
   
   Serial.println();

 }

 

lopezmil
Offline
Зарегистрирован: 17.02.2015

Он вроде работает, но может здесь что не так? Яведь с текстом не осободружен.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

все хорошо, если работает, ничего не нужно трогать. Много лишних переменных, но о них пусть компилятор позаботится.