avatar_UriBas

Моргалка на Arduino. Этюды для начинающих.

Автор UriBas, 08 Март 2017 в 16:08

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

Dkin

Нет оно постоянно. Это я в теории. Определил 745, пришел через 2 дня в гараж, температура изменилась, время прошло. Измениться же не должно?

ИС-Х

Цитата: UstAlexei от 24 Март 2017 в 18:11
Я предложил изменить делитель 1 / 2, но предостерег от превышения напряжения на входе контроллера.
А чего бояться-то? На входах процев стоят защитные диоды и ограничивают вх.напряжение до Uпит+0,5В. Главное - не превысить макс. ток этих диодов (где-то 20 мА). Если верхнее плечо делителя хотя бы 1 кОм, то от входного +-20В диоды вполне защитят.
Делитель нельзя брать слишком "делящим" иначе возрастает относительный уровень помех.
Моя первая моргалка: https://electrotransport.ru/index.php?msg=588520
Вторая моргалка: https://electrotransport.ru/index.php?topic=31184.0
Третья моргалка: https://electrotransport.ru/index.php?msg=1130718
Еще в багажнике валяется BL1204 на всякий пожарный...

UstAlexei

#110
при условии что у вас опорное тоже, измеряемое тоже, наводок нет - должно быть неизменно.
Предлагаю Вам встроить вместо AnalogRead() следующие дву функции, взяты от реношника.
Спойлер
void ConfigADC (void)
{
    ADCSRA |= (1 << ADEN) // Включаем АЦП
  |(1 << ADPS2)|(1 << ADPS1)|(1 << ADPS0); // устанавливаем предделитель преобразователя на 128

  ADMUX |= (1 << REFS1)|(1 << REFS0) // выставляем опорное напряжение 1,1
  |(0 << MUX0)|(0 << MUX1)|(0 << MUX2)|(0 << MUX3); // снимать сигнал будем с входа AC0
}

Спойлер
unsigned long GetADC (unsigned int StepOver, unsigned char razrid)
{
  unsigned long data = 0;
  unsigned int i;
  for (i = 1; i < StepOver; i++)
  {
    ADCSRA |= (1 << ADSC); // Запускаем преобразование
    while ((ADCSRA & (1 << ADIF)) == 0); // пока не будет выставлен флаг об окончании преобразования
    data += ADCW; // Считываем полученное значение
  }
  data = data >> razrid;
  return data;
}

Первую вызвать в функции setup
ConfigADC ();
вторую вызвать в теле вашего алгоритма
U = GetADC(32,4); // 32 - число шагов оверсемплинга, 4 - разряда сдвиг вправо.

Dkin

Не, спасибо конечно, таких кодов еще побаиваюсь. Хочу сделать понятную моргалку для себя и всех остальных, кто заинтересуется. Если будет работать на стандартном коде, пока трогать не буду.

Alex_Soroka

Цитата: UstAlexei от 24 Март 2017 в 19:08
Возможно Ваш делитель ловит много помех
вспомнил!
если вы применяете кварц для Атмега(или других проц.) то он сам на ноги свои может ловить импульсные помехи которые "срывают крышу" процессору.
Потому надо смотреть по месту: на режимах крышу сносит или нет ?
и заодно через эти ноги кварца(как и остальные ноги в принципе) тоже пролазят помехи, так что "внутренний источник" не зря советуют подключать не через резистор а через СМД-индуктивность...

Зная всеобщую любовь "паять на соплях" силовые цепи, да еще и длинными тонкими проводами - я вас просто предупреждаю  :hello:

а что там проц видит - можно тупо в ЕЕПРОМ записать кучку данных снятых с АЦП - а потом скачать в комп и посмотреть, если у вас ЖКИ нету и лень писать прогу для считывания-отображения.

xZ

#113
Цитата: Dunkel от 23 Март 2017 в 23:08
Все так же, как с ардуино. Я просто уже спалил пару UNO в процессе экспериментов, теперь сначала на кошках тренируюсь.
Почитайте:

https://mysku.ru/blog/china-stores/36691.html

Может нужно GND наны подключать не к - акб а к - зарядки? В первом случае по схеме из шапки не будет мосфет работать, во втором- делитель

реношник

В посте №109 я дал ссылку для экспериментов по измерению напряжения !!!  :bravo:

==============================

Вот еще "гибридный" код с результатом по времени....  :hello:

unsigned int data;
float V;
unsigned long time;

void setup() {
analogReference(DEFAULT);                      // DEFAULT INTERNAL использовать Vcc как AREF
Serial.begin(57600);
ADCSRA= ADCSRA&0xF8;                         // SET ADPS[2:0]->0 Prescaler = 2
}

void loop() {
time = micros();
data = analogRead(A3);                         // Считываем полученное значение
time = micros() - time;
V = (float) data * 0.0047031;                   // Переводим в вольты
Serial.print("V = "); Serial.print(V, 3); Serial.print(" V ");
Serial.print("T = "); Serial.print(time); Serial.println(" mks");
delay (500);
}

V = 4.811 V T = 3 mks
V = 4.811 V T = 3 mks
V = 4.811 V T = 3 mks
V = 4.811 V T = 3 mks
V = 4.811 V T = 3 mks
V = 4.811 V T = 3 mks
V = 4.811 V T = 3 mks
V = 4.811 V T = 3 mks

UstAlexei

#115
[user]реношник[/user], А какой смысл с таким прескалером измерять? Ведь погрешность измерения растет! Предлагают частоту работы АЦП выбирать до 200кГц, а вы на всех 8МГц работаете.
13 - 260μs Conversion Time - Время измерения по даташиту от 13 до 260 микросекунд.

Яков93

[user]реношник[/user], шикарно!
Т.е. если просто добавить в setup строчку
ADCSRA= ADCSRA&0xF8;
то можно ускорить analogRead ?
К сожалению я вообще не понял что эта строчка значит, а от нее все аналоговые порты так ускоряются или только конкретно A3?
И такое стабильное напряжение - 4.811 вплоть до 1 тысячной без усреднений... это реальное измерение или просто абстрактная цифра?

реношник

Цитата: UstAlexei от 24 Март 2017 в 21:03
[user]реношник[/user], А какой смысл с таким прескалером измерять? Ведь погрешность измерения растет! Предлагают частоту работы АЦП выбирать до 200кГц, а вы на всех 8МГц работаете.

Просто на практике погрешность не зафиксировал...   А вообще вы полностью правы !!!

Dunkel

Цитата: Dkin от 24 Март 2017 в 18:37
Я что-то не совсем понимаю, подскажите в моем случае. Напряжение питания ардуино (через ее встроенный стабилизатор) - АКБ.

[user]Dkin[/user], Запитывать контроллер от заряжаемой АКБ плохая идея.
Во-первых АКБ может быть совсем дохлая, и на ней даже 5В не будет - контроллер просто не включится.
Во-вторых на АКБ от источника питания идут импульсы достаточно большого напряжения, которое может попасть на контроллер и спалить стабилизатор.

Лучше запитайте контроллер от источника питания через отдельную понижайку. Она стоит меньше доллара.

Многофункциональная облачная моргалка/логгер:
https://morgalka78.wordpress.com/

Dkin

Цитата: Alex_Soroka от 24 Март 2017 в 19:34
Зная всеобщую любовь "паять на соплях" силовые цепи, да еще и длинными тонкими проводами - я вас просто предупреждаю  :hello:

Использую гибкие медные провода 4 мм2 от ЗУ к моргалке, потом 0,4 м где-то до АКБ, клеммы, крокодилов нет.

Цитата: UstAlexei от 24 Март 2017 в 21:03
[user]реношник[/user], А какой смысл с таким прескалером измерять? Ведь погрешность измерения растет!

Верно, зачем гнаться за скоростью, если частота 35 Гц?

Цитата: Dunkel от 24 Март 2017 в 21:16
[user]Dkin[/user], Запитывать контроллер от заряжаемой АКБ плохая идея.
Лучше запитайте контроллер от источника питания через отдельную понижайку. Она стоит меньше доллара.

Я наметил цель на простоту схемы и кода. Если ардуино будет плохо работать или сгорит будем думать. Можно также использовать КР142ЕН5В (5В, 1,5А).

реношник

Цитата: Яков93 от 24 Март 2017 в 21:05
[user]реношник[/user], шикарно!
Т.е. если просто добавить в setup строчку
ADCSRA= ADCSRA&0xF8;
то можно ускорить analogRead ?
К сожалению я вообще не понял что эта строчка значит, а от нее все аналоговые порты так ускоряются или только конкретно A3?
И такое стабильное напряжение - 4.811 вплоть до 1 тысячной без усреднений... это реальное измерение или просто абстрактная цифра?


1 - пин можно взять любой (аналоговый)
2 - просто соединил Vcc с А3

xZ

#121
Цитата: реношник от 24 Март 2017 в 20:39
В посте №109 я дал ссылку для экспериментов по измерению напряжения !!!  :bravo:

==============================

Вот еще "гибридный" код с результатом по времени....  :hello:

unsigned int data;
float V;
unsigned long time;

void setup() {
analogReference(DEFAULT);                      // DEFAULT INTERNAL использовать Vcc как AREF
Serial.begin(57600);
ADCSRA= ADCSRA&0xF8;                         // SET ADPS[2:0]->0 Prescaler = 2
}

void loop() {
time = micros();
data = analogRead(A3);                         // Считываем полученное значение
time = micros() - time;
V = (float) data * 0.0047031;                   // Переводим в вольты
Serial.print("V = "); Serial.print(V, 3); Serial.print(" V ");
Serial.print("T = "); Serial.print(time); Serial.println(" mks");
delay (500);
}

V = 4.811 V T = 3 mks
V = 4.811 V T = 3 mks
V = 4.811 V T = 3 mks
V = 4.811 V T = 3 mks
V = 4.811 V T = 3 mks
V = 4.811 V T = 3 mks
V = 4.811 V T = 3 mks
V = 4.811 V T = 3 mks

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

Dkin

Уважаемые коллеги, друзья!

Испытал версию программы с отсечкой по напряжению. Измерение напряжения отсечки получилось добиться до сотой вольта с точным совпадением по мультиметру.

Спойлер


// Общие настройки - Несущая частота
float freq = 35.00; // частота в Гц (от 1 до 350)
float skv1 = 50.00; // коэффициент заполнения (от 1 до 99)

// 1 этап Модулирующие импульсы
long zar1 = 30; // время заряда в сек (от 1 сек)
long pauseosn1 = 10; // время паузы в сек (от 1 сек)

// 2 этап работа отсечки
float Uots = 14.40; // напряжение отсечки
long pauseots1 = 30; // время паузы в сек (от 1 сек)
float koeffU = 0.0276391555; //коэффициент делителя напряжения - подобрать опытным путем, чтобы отсечка срабатывала при Uots

float Uots1 = Uots/koeffU*10;
float impnes1 = 0.00;
float pausenes1 = 0.00;
long previousMillis = 0;
float Utek = 0.00;

void setup()
{
   pinMode(13, OUTPUT); // используем 13 выход для управления ключом, на нем также висит синий светодиод, располагающийся на плате, для наглядности
   pinMode(10, OUTPUT); // светодиод отсечка
   pinMode(12, OUTPUT); // светодиод заряд
   pinMode(0, INPUT); // вход A0 с делителя напряжения
   impnes1 = 10 * skv1 / freq; // расчет импульса заряда несущей частоты
   pausenes1 = 10 * (100 - skv1) / freq; // расчет паузы несущей частоты
}
void loop()
{
label2:
// расчет основного цикла заряд/пауза
unsigned long currentMillis = millis();
if (currentMillis - previousMillis > zar1*1000) // если время заряда истекло
{
    digitalWrite(13, LOW); // выключаем ключ
    digitalWrite(12, LOW); // выключаем светодиод заряд
    delay (pauseosn1*1000); // пауза основного цикла
    currentMillis = millis();
    previousMillis = currentMillis;
}
// работа импульсов несущей частоты
  digitalWrite(12, HIGH); // включаем светодиод заряд
  digitalWrite(13, HIGH); // включаем ключ
  delay(impnes1 );                     
  Utek=0;
  for (int i = 0; i <10; i ++)  Utek+=analogRead(A0); // измеряем напряжение на входе А0 10 раз подряд и прибавляем друг к другу
  if (Utek > Uots1) // если измеренное напряжение больше напряжения отсечки
{
goto label1; // перейти на паузу отсечки
}
  digitalWrite(13, LOW); // отключаем ключ
  delay( pausenes1 );
  goto label2; // пропустить паузу отсечки
label1:
    digitalWrite(13, LOW); // выключаем ключ
    digitalWrite(12, LOW); // отключаем светодиод заряд
    digitalWrite(10, HIGH); // включаем светодиод отсечка
    delay (200);
    digitalWrite(10, LOW); // отключаем светодиод отсечка
    delay (200);
    digitalWrite(10, HIGH); // включаем светодиод отсечка
    delay (200);
    digitalWrite(10, LOW); // отключаем светодиод отсечка
    delay (200);
    digitalWrite(10, HIGH); // включаем светодиод отсечка
    delay (200);
    digitalWrite(10, LOW); // отключаем светодиод отсечка
    delay (pauseots1*1000-1000); //пауза после отсечки минус 1 сек (мигание светодиода отсечка)
    currentMillis = millis();
    previousMillis = currentMillis;
}


Сейчас выложу ее в первый пост с подробным описанием. Надеюсь, что реализация этого достаточно простого проекта позволит перейти к более сложным идеям. Сам перехожу к осмыслению алгоритма, который посоветовал т. UriBas в посте №45, для этого потребуется время. Выражаю благодарность всем участникам, кто поддерживал технически и морально, желаю удачи и успехов!

Dunkel

[user]Dkin[/user],

  pinMode(0, INPUT); // вход A0 с делителя напряжения

Вы устанавливаете на вход цифровой пин 0, а не аналоговый А0. Цифровые 0 и 1 лучше не трогать, это Rx Tx.

Аналоговые входы (analog pins) могут быть использованы как цифровые вход/выходы (digital pins). Обращение к ним идет по номерам от 14 (для аналогового входа 0) до 19 (для аналогового входа 5).
Многофункциональная облачная моргалка/логгер:
https://morgalka78.wordpress.com/

Dkin

Цитата: UstAlexei от 25 Март 2017 в 07:36
для осмысление поста 45 вам просто необходимо применить стороннюю функцию по чтению данных с АЦП из поста 118 https://electrotransport.ru/index.php?msg=1046947 без нее вам не измерить скорости с требуемой точностью

Пока для меня все это не понятно, буду разбираться, но в любом случае, первый урок выполнен успешно!

Цитата: Dunkel от 25 Март 2017 в 15:03
Вы устанавливаете на вход цифровой пин 0, а не аналоговый А0. Цифровые 0 и 1 лучше не трогать, это Rx Tx.

Аналоговые входы (analog pins) могут быть использованы как цифровые вход/выходы (digital pins). Обращение к ним идет по номерам от 14 (для аналогового входа 0) до 19 (для аналогового входа 5).

На моей плате А0-А6 отдельно, RX0, TX1 в другой стороне, или они параллельно (А0 - RX0, А1 - TX1) подключены?

Dunkel

[user]Dkin[/user],  просто уберите эту строчку, она относится к цифровому порту 0, а не к аналоговому А0.
Цифровые порты 0 и 1 это Rx Tx.
Многофункциональная облачная моргалка/логгер:
https://morgalka78.wordpress.com/