Ви не увійшли.
...руки іще не дойшли перевірити... з роботою -завал (2-3 дні щоб закінчити замоілення), як перевірю - повідомлю новини
Дякую всім
Honey пише:В прерывании делать преобразование к float и деление... пропуски импульсов гарантированы.
Возможно, код не мой, где-то стырил (так же как и ТС свой ), уже не помню где. В протеусе работает, в железе не проверял. Но для ведроидного колайдера ТС подойдет
"ведроидный коллайдер"
Я так і назву
Розсмішили, дякую
В прерывании делать преобразование к float и деление... пропуски импульсов гарантированы.
Возможно, код не мой, где-то стырил (так же как и ТС свой ), уже не помню где. В протеусе работает, в железе не проверял. Но для ведроидного колайдера ТС подойдет
void isr() { rpm=60/((float)(micros()-passtime)/1000000); passtime=micros(); }
В прерывании делать преобразование к float и деление... пропуски импульсов гарантированы.
то не важко було б перекласти попередження та почитати про типи даних https://doc.arduino.ua/ru/prog/Int
Не знав - дякую... помислю )))
olegxter пише:D:Arduinofull_relayR_millis_RPM_modR_millis_RPM_mod.ino:168:10: warning: integer overflow in expression [-Woverflow]
Якщо ви дійсно
olegxter пише:я жив і працював у Франції довго ))), в Solidworks працюю теж на en/fr - привичка)
то не важко було б перекласти попередження та почитати про типи даних https://doc.arduino.ua/ru/prog/Int
Якщо у вас на валу один гамніт, то я б вашу функцію isr()
записав би у такому виглядіvoid isr() { rpm=60/((float)(micros()-passtime)/1000000); passtime=micros(); }
Відповідно у loop формулу rpm і наступну строку закоментувати/видалити
Доброго дня. так зіичайно що переклав.... але то мало ))) потрібно ще розуміти ( переповнення яке? - нерозумію) про типи даних прочитаю.
Дякую
Ще раз, я дав робочий (апробований з сенсором 3144) шматок коду для перевірки Вашої апаратної частини з RPM (резистор додавати не обов'язково):
volatile uint16_t count; volatile uint16_t rps; const uint8_t pulsesPerRound = 1; /* Number of pulses per one round */ void initExternalInterrupt0(void) { EICRA |= (1 << ISC00) | (1 << ISC01); /* The rising edge of INT0 generates an interrupt request */ EIMSK |= (1 << INT0); /* INT0: External Interrupt Request 0 Enable*/ } void initTimer1(void) { TCCR1A = 0x00; /* Normal mode */ TCCR1B = 0b00001101; /* SET "1024" prescaler */ TIMSK1 = 0b00000010; /* Enable Output Compare A Match Interrupt */ OCR1A = 15625; /* Ticks per 1 second at 16MHz */ } ISR(INT0_vect) { count++; /* Increment pulses count */ EIFR |= (1 << INTF0); /* Clear interrupt flag */ } ISR(TIMER1_COMPA_vect) { rps = count; /* Number of round per second */ count = 0; } void setup() { PORTD |= (1 << PD2); Serial.begin(9600); initExternalInterrupt0(); initTimer1(); sei(); } void loop() { Serial.print("RPM = "); Serial.println(rps * 60 / pulsesPerRound); /* RPM = RPS*60 / Pulses per round */ _delay_ms(1000); }
Вам лише потрібно підставити своє значення pulsesPerRound (зараз там 1) - кількість імпульсів за один повний оберт (скільки магнітів на роторі?). Якщо все запрацює - просто вставте робочий код замість ваших шматків коду з RPM. Ще одне, погана ідея живити сенсор від I/O піна (у вас це 3 рядки: #define Vcc_pin 3 // pin +5v Hall Sensor, pinMode(Vcc_pin, OUTPUT); // pin Hall sensor output та digitalWrite(Vcc_pin, HIGH); // pin Hall sensor VCC +5v), просто підключіть вивід сенсора Vcc (+5В) до однойменного вивода на платі.
Доброго дня. Дякую, дуже дякую - код спробую сьогодні - відпишу, на платі вже не залишилось вільних +5 тому прийшлось додавати...
Взагалі ідея була замінити реле на симістор + оптопара + повіcити все це на регістр 74НС595 ...
Але то наступний крок.
без поля - на виході HIGH.
У такому разі RISING треба замінити на FALLING
D:Arduinofull_relayR_millis_RPM_modR_millis_RPM_mod.ino:168:10: warning: integer overflow in expression [-Woverflow]
Якщо ви дійсно
я жив і працював у Франції довго ))), в Solidworks працюю теж на en/fr - привичка)
то не важко було б перекласти попередження та почитати про типи даних https://doc.arduino.ua/ru/prog/Int
Якщо у вас на валу один гамніт, то я б вашу функцію isr()
записав би у такому вигляді
void isr() {
rpm=60/((float)(micros()-passtime)/1000000);
passtime=micros();
}
Відповідно у loop формулу rpm і наступну строку закоментувати/видалити
Ще раз, я дав робочий (апробований з сенсором 3144) шматок коду для перевірки Вашої апаратної частини з RPM (резистор додавати не обов'язково):
volatile uint16_t count;
volatile uint16_t rps;
const uint8_t pulsesPerRound = 1; /* Number of pulses per one round */
void initExternalInterrupt0(void)
{
EICRA |= (1 << ISC00) | (1 << ISC01); /* The rising edge of INT0 generates an interrupt request */
EIMSK |= (1 << INT0); /* INT0: External Interrupt Request 0 Enable*/
}
void initTimer1(void)
{
TCCR1A = 0x00; /* Normal mode */
TCCR1B = 0b00001101; /* SET "1024" prescaler */
TIMSK1 = 0b00000010; /* Enable Output Compare A Match Interrupt */
OCR1A = 15625; /* Ticks per 1 second at 16MHz */
}
ISR(INT0_vect)
{
count++; /* Increment pulses count */
EIFR |= (1 << INTF0); /* Clear interrupt flag */
}
ISR(TIMER1_COMPA_vect)
{
rps = count; /* Number of round per second */
count = 0;
}
void setup()
{
PORTD |= (1 << PD2);
Serial.begin(9600);
initExternalInterrupt0();
initTimer1();
sei();
}
void loop() {
Serial.print("RPM = ");
Serial.println(rps * 60 / pulsesPerRound); /* RPM = RPS*60 / Pulses per round */
_delay_ms(1000);
}
Вам лише потрібно підставити своє значення pulsesPerRound (зараз там 1) - кількість імпульсів за один повний оберт (скільки магнітів на роторі?). Якщо все запрацює - просто вставте робочий код замість ваших шматків коду з RPM. Ще одне, погана ідея живити сенсор від I/O піна (у вас це 3 рядки: #define Vcc_pin 3 // pin +5v Hall Sensor, pinMode(Vcc_pin, OUTPUT); // pin Hall sensor output та digitalWrite(Vcc_pin, HIGH); // pin Hall sensor VCC +5v), просто підключіть вивід сенсора Vcc (+5В) до однойменного вивода на платі.
Honey пише:akapulko пише:Так, дійсно, може спрацювати проста заміна рядка:
pinMode(SIG_pin, INPUT); // pin signal Hall sensor
на рядок:
PORTD |= 1 << PD2; // Internal Pull-upТогда уж лучше заменить INPUT на INPUT_PULLUP, чтобы не было в коде мешанины.
Достаточно в формуле заменить 60*1000 на 60000 и не заниматься фигней
Змінив рядок, змінив формулу - стало значно краще RPM=0 тільки деколи проскакує = 30861
D:Arduinofull_relayR_millis_RPM_modR_millis_RPM_mod.ino: In function 'void loop()':
D:Arduinofull_relayR_millis_RPM_modR_millis_RPM_mod.ino:168:10: warning: integer overflow in expression [-Woverflow]
rpm = 60*1000/(millis() - passtime)*counter;
~~^~~~~
Скетч використовує 7976 байтів (3%) місця зберігання для програм. Межа 253952 байтів.
Глобальні змінні використовують 346 байтів (4%) динамічної пам’яті, залишаючи 7846 байтів для локальних змінних. Межа 8192 байтів.
Повідомлення про помилку
akapulko пише:Рекомендація: Прибрати модуль KY-003, використати "голий" сенсор (3144 чи подібний), між виводами Vcc та Out -> резистор 10-20k.
Если модуль "черный" то он и так голый, достаточно добавить резистор. Если красный - то смотреть к какому выходу подключен, аналоговый или цифровой.
akapulko пише:Код для перевірки ...
Зачем такие сложности. Код ТС тоже вполне подойдет. Нужно только правильно разобраться с формулой.
Доброго вечора.
Модуль - чорний, датчик 3144EUA-S, резистор 680 Ом та лед індикатор,без поля - на виході HIGH. при набллиженні магніта до датчика - загоряється лед
akapulko пише:Так, дійсно, може спрацювати проста заміна рядка:
pinMode(SIG_pin, INPUT); // pin signal Hall sensor
на рядок:
PORTD |= 1 << PD2; // Internal Pull-upТогда уж лучше заменить INPUT на INPUT_PULLUP, чтобы не было в коде мешанины.
Достаточно в формуле заменить 60*1000 на 60000 и не заниматься фигней
Так, дійсно, може спрацювати проста заміна рядка:
pinMode(SIG_pin, INPUT); // pin signal Hall sensor
на рядок:
PORTD |= 1 << PD2; // Internal Pull-up
Тогда уж лучше заменить INPUT на INPUT_PULLUP, чтобы не было в коде мешанины.