#1 2021-12-07 23:24:21

olegxter
Учасник
Зареєстрований: 2021-07-25
Повідомлень: 18

Допомога у програмуванні

Доброго вечора.
Шановна спільнота - прошу вашої допомоги.
Підкажіть , будь- ласка, де шукати помилку...

Коротко - MEGA  2560 -  по таймеру керує:
1. Вкл/Викл помпа, частота 3 min
2. Вкл/Викл реле, частота 140ms
3. Підрахунок RPM по датчику
4. Вимірювання температури двома датчиками
5. Вивід значень в порт, оновлення 1s

Ось код:

[        /*
                      test RPM + temperature
        
            */
           
    #include <OneWire.h>        //
   
    #include <DallasTemperature.h>        //
   
    #define ONE_WIRE_BUS A0        // pin data sensor
   
    OneWire oneWire(ONE_WIRE_BUS);    // creer objects communication OneWire ( themperature)
    DallasTemperature sensors(&oneWire);          // done objects for DallasTemperature

    uint8_t sensor1[8] = { 0x28, 0x5C, 0xC1, 0x05, 0x00, 0x00, 0x00, 0x23};   // adress Sensor 1
    uint8_t sensor2[8] = { 0x28, 0x20, 0xEA, 0x05, 0x00, 0x00, 0x00, 0x4E};   // adress Sensor 2
   
    #define motorPin 46     // pin motor MOSFET/operation
    #define   Vcc_pin 3     // pin +5v Hall Sensor
    #define SIG_pin 2       // pin signal Hall Sensor
   
    #define C1_C_in 22        // C 1 Cold  pin 22 R 1
    #define C1_H_in 23        // C 1 Hot   pin 23 R 2
    #define C1_C_out 24       // C 1 Cold  pin 24 R 3             
    #define C1_H_out 25       // C 1 Hot   pin 25 R 4             
                   
    #define C4_C_in 26        // C 4 Cold  pin 26 R 5
    #define C4_H_in 27        // C 4 Hot   pin 27 R 6
    #define C4_C_out 28       // C 4 Cold  pin 28 R 7
    #define C4_H_out 29       // C 4 Hot   pin 29 R 8

    #define C2_C_in 30        // C 2 Cold  pin 30 R 9
    #define C2_H_in 31        // C 2 Hot   pin 31 R 10
    #define C2_C_out 32       // C 2 Cold  pin 32 R 11
    #define C2_H_out 33       // C 2 Hot   pin 33 R 12

    #define C5_C_in 34        // C 5 Cold  pin 34 R 13
    #define C5_H_in 35        // C 5 Hot   pin 35 R 14
    #define C5_C_out 36       // C 5 Cold  pin 36 R 15
    #define C5_H_out 37       // C 5 Hot   pin 37 R 16

    #define C3_C_in 38        // C 3 Cold  pin 38 R 17
    #define C3_H_in 39        // C 3 Hot   pin 39 R 18
    #define C3_C_out 40       // C 3 Cold  pin 40 R 19
    #define C3_H_out 41       // C 3 Hot   pin 41 R 20

    #define C6_C_in 42        // C 6 Cold  pin 42 R 21
    #define C6_H_in 43        // C 6 Hot   pin 43 R 22
    #define C6_C_out 44       // C 6 Cold  pin 44 R 23
    #define C6_H_out 45       // C 6 Hot   pin 45 R 24

    #define RPM_INTERVAL 1000UL        // update RPM
    #define Pump_INTERVAL 60000UL      // interval ON/OFF pump
    #define Relay_INTERVAL 840UL      // relay operation
    #define SERIAL_SPEED 9600          // Speed serial (com-port)
   
    volatile byte counter;
    unsigned int rpm;
    unsigned long passtime;
   
    void isr()

    {

   //Each rotation, this interrupt function is run twice, so take that into consideration for
   //calculating RPM
   //Update count

           counter++;
    }
   
    void setup() {
   
    Serial.begin(SERIAL_SPEED);
   
                // Hall sensor operation

    pinMode(Vcc_pin, OUTPUT);        // pin Hall sensor output
    digitalWrite(Vcc_pin, HIGH);     // pin Hall sensor VCC +5v
    pinMode(SIG_pin, INPUT);         // pin signal Hall sensor
   
    attachInterrupt(0, isr, RISING); //Interrupts are called on Rise of Input
    rpm = 0;
    counter = 0;
    passtime = 0;                    //Initialise the values
      
            // pump
           
    pinMode(motorPin, OUTPUT);       // motor output
       
            // relay
 
    pinMode(C1_C_in, OUTPUT);      //  pin 22 output:
    pinMode(C1_H_in, OUTPUT);      //  pin 23 output:
    pinMode(C1_C_out, OUTPUT);     //  pin 24 output:
    pinMode(C1_H_out, OUTPUT);     //  pin 25 output:

    pinMode(C4_C_in, OUTPUT);      //  pin 26 output:
    pinMode(C4_H_in, OUTPUT);      //  pin 27 output:
    pinMode(C4_C_out, OUTPUT);     //  pin 28 output:
    pinMode(C4_H_out, OUTPUT);     //  pin 29 output:

    pinMode(C2_C_in, OUTPUT);      //  pin 30 output:
    pinMode(C2_H_in, OUTPUT);      //  pin 31 output:
    pinMode(C2_C_out, OUTPUT);     //  pin 32 output:
    pinMode(C2_H_out, OUTPUT);     //  pin 33 output:

    pinMode(C5_C_in, OUTPUT);      //  pin 34 output:
    pinMode(C5_H_in, OUTPUT);      //  pin 35 output:
    pinMode(C5_C_out, OUTPUT);     //  pin 36 output:
    pinMode(C5_H_out, OUTPUT);     //  pin 37 output:

    pinMode(C3_C_in, OUTPUT);      //  pin 38 output:
    pinMode(C3_H_in, OUTPUT);      //  pin 39 output:
    pinMode(C3_C_out, OUTPUT);     //  pin 40 output:
    pinMode(C3_H_out, OUTPUT);     //  pin 41 output:

    pinMode(C6_C_in, OUTPUT);      //  pin 42 output:
    pinMode(C6_H_in, OUTPUT);      //  pin 43 output:
    pinMode(C6_C_out, OUTPUT);     //  pin 44 output:
    pinMode(C6_H_out, OUTPUT);     //  pin 45 output:

            // Turn relay OFF ;

    digitalWrite(C1_C_in, HIGH);   // R  1 OFF
    digitalWrite(C1_H_in, HIGH);   // R  2 OFF
    digitalWrite(C1_C_out, HIGH);  // R  3 OFF
    digitalWrite(C1_H_out, HIGH);  // R  4 OFF

    digitalWrite(C4_C_in, HIGH);   // R  5 OFF
    digitalWrite(C4_H_in, HIGH);   // R  6 OFF
    digitalWrite(C4_C_out, HIGH);  // R  7 OFF
    digitalWrite(C4_H_out, HIGH);  // R  8 OFF

    digitalWrite(C2_C_in, HIGH);   // R  9 OFF
    digitalWrite(C2_H_in, HIGH);   // R 10 OFF
    digitalWrite(C2_C_out, HIGH);  // R 11 OFF
    digitalWrite(C2_H_out, HIGH);  // R 12 OFF

    digitalWrite(C5_C_in, HIGH);   // R 13 OFF
    digitalWrite(C5_H_in, HIGH);   // R 14 OFF
    digitalWrite(C5_C_out, HIGH);  // R 15 OFF
    digitalWrite(C5_H_out, HIGH);  // R 16 OFF

    digitalWrite(C3_C_in, HIGH);   // R 17 OFF
    digitalWrite(C3_H_in, HIGH);   // R 18 OFF
    digitalWrite(C3_C_out, HIGH);  // R 19 OFF
    digitalWrite(C3_H_out, HIGH);  // R 20 OFF

    digitalWrite(C6_C_in, HIGH);   // R 21 OFF
    digitalWrite(C6_H_in, HIGH);   // R 22 OFF
    digitalWrite(C6_C_out, HIGH);  // R 23 OFF
    digitalWrite(C6_H_out, HIGH);  // R 24 OFF

    }

    void loop() {       
   
                // update RPM;
               
    static unsigned long prevRpmTime  = 0;
    if(millis() - prevRpmTime > RPM_INTERVAL){
    prevRpmTime = millis();

    detachInterrupt(0);                //Interrupts are disabled
    rpm = 60*1000/(millis() - passtime)*counter;
    passtime = millis();
    counter = 0;
    attachInterrupt(0, isr, RISING);   //Restart the interrupt processing

    Serial.print("Reading - RPM = ");
    Serial.println(rpm);
   
    sensors.requestTemperatures();      //temp C print
 
    Serial.print("Sensor 1: ");
    printTemperature(sensor1);
 
    Serial.print("Sensor 2: ");
    printTemperature(sensor2);
   
    Serial.println();
   
        }       
                // time motor
   
    static unsigned long prevPumpTime = 0;
    if(millis() - prevPumpTime > Pump_INTERVAL){
    prevPumpTime = millis();
    digitalWrite(motorPin, HIGH);
    }else{
    digitalWrite(motorPin, LOW);
   
        }       
                // RELAY operation
               
    static unsigned long prevRelayTime = 0;          // save the time of the last switch 
    if(millis() - prevRelayTime > Relay_INTERVAL) {  //check whether the required interval has passed, if so
    prevRelayTime = millis();
        }
                   // C1_H+C3_C - 1
       
    if(millis() - prevRelayTime > 0*Relay_INTERVAL/6&&millis() - prevRelayTime < 1*Relay_INTERVAL/6) {
      
        digitalWrite(C2_C_in, HIGH);      //  30 OFF
        digitalWrite(C2_H_out, HIGH);     //  33 OFF
        digitalWrite(C3_C_out, HIGH);     //  40 OFF
        digitalWrite(C6_H_in, HIGH);      //  43 OFF 
        digitalWrite(C6_H_out, HIGH);     //  45 OFF
      
        digitalWrite(C1_H_in , LOW);      //  23 ON
        digitalWrite(C1_H_out, LOW);      //  25 ON
        digitalWrite(C4_C_out, LOW);      //  28 ON
        digitalWrite(C3_C_in, LOW);       //  38 ON
        digitalWrite(C3_H_out, LOW);      //  41 ON     
        }
                   //  C2_H+C4_C - 2
         
    if(millis() - prevRelayTime > 1*Relay_INTERVAL/6&&millis() - prevRelayTime < 2*Relay_INTERVAL/6) {
      
        digitalWrite(C1_H_in, HIGH);      //  23 OFF
        digitalWrite(C1_H_out, HIGH);     //  25 OFF
        digitalWrite(C4_C_out, HIGH);     //  28 OFF
        digitalWrite(C3_C_in, HIGH);      //  38 OFF 
        digitalWrite(C3_H_out, HIGH);     //  41 OFF         
   
        digitalWrite(C4_C_in, LOW);       //  26 ON
        digitalWrite(C4_H_out, LOW);      //  29 ON
        digitalWrite(C2_H_in, LOW);       //  31 ON
        digitalWrite(C2_H_out, LOW);      //  33 ON
        digitalWrite(C5_C_out, LOW);      //  36 ON     
        }
                  //  C3_H+C5_C - 3
       
  if(millis() - prevRelayTime > 2*Relay_INTERVAL/6&&millis() - prevRelayTime < 3*Relay_INTERVAL/6) {
      
        digitalWrite(C4_C_in, HIGH);      //  26 OFF
        digitalWrite(C4_H_out, HIGH);     //  29 OFF
        digitalWrite(C2_H_in, HIGH);      //  31 OFF
        digitalWrite(C2_H_out, HIGH);     //  33 OFF 
        digitalWrite(C5_C_out, HIGH);     //  36 OFF         
   
        digitalWrite(C5_C_in, LOW);       //  34 ON
        digitalWrite(C5_H_out, LOW);      //  37 ON
        digitalWrite(C3_H_in, LOW);       //  39 ON
        digitalWrite(C3_H_out, LOW);      //  41 ON
        digitalWrite(C6_C_out, LOW);      //  44 ON     
        }
                   // C4_H+C6_C - 4
       
  if(millis() - prevRelayTime > 3*Relay_INTERVAL/6&&millis() - prevRelayTime < 4*Relay_INTERVAL/6) {
      
        digitalWrite(C5_C_in, HIGH);      //  34 OFF
        digitalWrite(C5_H_out, HIGH);     //  37 OFF
        digitalWrite(C3_H_in, HIGH);      //  39 OFF
        digitalWrite(C3_H_out, HIGH);     //  41 OFF 
        digitalWrite(C6_C_out, HIGH);     //  44 OFF         
   
        digitalWrite(C1_C_out, LOW);      //  24 ON
        digitalWrite(C4_H_in, LOW);       //  27 ON
        digitalWrite(C4_H_out, LOW);      //  29 ON
        digitalWrite(C6_C_in, LOW);       //  42 ON
        digitalWrite(C6_H_out, LOW);      //  45 ON     
        }
                   // C5_C+C1_C - 5
       
  if(millis() - prevRelayTime > 4*Relay_INTERVAL/6&&millis() - prevRelayTime < 5*Relay_INTERVAL/6) {
      
        digitalWrite(C1_C_out, HIGH);     //  24 OFF
        digitalWrite(C4_H_in, HIGH);      //  27 OFF
        digitalWrite(C4_H_out, HIGH);     //  29 OFF
        digitalWrite(C6_C_in, HIGH);      //  42 OFF 
        digitalWrite(C6_H_out, HIGH);     //  45 OFF         
         
        digitalWrite(C1_C_in, LOW);       //  22 ON
        digitalWrite(C1_H_out, LOW);      //  25 ON
        digitalWrite(C2_C_out, LOW);      //  32 ON
        digitalWrite(C5_H_in, LOW);       //  35 ON
        digitalWrite(C5_H_out, LOW);      //  37 ON     
        }
                   // C6_H+C2_C - 6
   
  if(millis() - prevRelayTime > 5*Relay_INTERVAL/6&&millis() - prevRelayTime < 6*Relay_INTERVAL/6) {
      
        digitalWrite(C1_C_in, HIGH);      //  22 OFF
        digitalWrite(C1_H_out, HIGH);     //  25 OFF
        digitalWrite(C2_C_out, HIGH);     //  32 OFF
        digitalWrite(C5_H_in, HIGH);      //  35 OFF 
        digitalWrite(C5_H_out, HIGH);     //  37 OFF         
        
        digitalWrite(C2_C_in, LOW);       //  30 ON
        digitalWrite(C2_H_out, LOW);      //  33 ON
        digitalWrite(C3_C_out, LOW);      //  40 ON
        digitalWrite(C6_H_in, LOW);       //  43 ON
        digitalWrite(C6_H_out, LOW);      //  45 ON     
        }
   
    }
       
    void printTemperature(DeviceAddress deviceAddress)
    {
    float tempC = sensors.getTempC(deviceAddress);
    Serial.print(tempC);
    Serial.print((char)176);
    Serial.print("  °C/  ");
    }
]

                      Проблеми

1, При компілюванні - з компа - видає помилку у формулі RPM; - з ноута - все нормально...
2, зависають реле на 5-му "блоці" - // C5_C+C1_C - 5 -далі реле ( всі ) не працюють -висить
3, Виводить дані з оновленням в одну сек - добре, температура -добре, але показники RPM - при нерухомому валі - RPM = 30568
     при обертанні валу рукою - приблизно 1 об/сек - датчик спрацьовує 1 раз - RPM - 60000+

  В яку сторону копати? щоб було нормально...
  Я сам не програміст і не вчусь, просто задумав зробити одну "штукенвію" так що прийшлось...

  Буду дуже вдячний за  будь-яку допомогу.
  На глінтвейн, на здоров"я, буду просто зобовязаний підкинути wink
  Дякую всім.

Остання редакція olegxter (2021-12-08 21:50:29)

Неактивний

#2 2021-12-08 08:45:51

vvr
Учасник
Зареєстрований: 2015-04-12
Повідомлень: 792

Re: Допомога у програмуванні

а не смущает, что заокеанский пионер, особо не смыслящий в программировании, использует библиотеку с почти секундными задержками ?
В яку сторону копати? - копать в сторону переписывания программы с нуля (полное техзадание и денёг на несколько коньяков)

Неактивний

#3 2021-12-08 09:16:15

Kaka
Учасник
Зареєстрований: 2018-03-21
Повідомлень: 410

Re: Допомога у програмуванні

olegxter пише:

2. Вкл/Викл реле, частота 140ms

Оххх

Неактивний

#4 2021-12-08 09:55:57

olegxter
Учасник
Зареєстрований: 2021-07-25
Повідомлень: 18

Re: Допомога у програмуванні

vvr пише:

а не смущает, что заокеанский пионер, особо не смыслящий в программировании, использует библиотеку с почти секундными задержками ?
В яку сторону копати? - копать в сторону переписывания программы с нуля (полное техзадание и денёг на несколько коньяков)

Доброго дня.
Я не "особо не смыслящий" я скоріше зовсім... це мій 5 скетч))) iз  // delay //  все супер але тільки реле, від температури можу відказатись, але від RPM - ну просто ніяк....
Не заокеанський, та не піонер  tongue  Я тут у Івано-Франківську. 
Про коньяк - не питання, скільки і куда?
Підозріваю проблема саме з Dallas - швидкість оновлення 750ms ? так? - тому і йде конфлікт з мілліс?, так якщо запускати без датчиків  ( закоментувати ) то реле працює , з датчиком обертів - та сама проблема.
Трохи не точно описав із самого початку:
Цикл
Блок 1 - ON 140ms / OFF
Блок 2 -  ON 140ms / OFF
Блок 3 - ON 140ms / OFF
Блок 4 -  ON 140ms / OFF
Блок 5 - ON 140ms / OFF
Блок 6 -  ON 140ms / OFF
Буду вдячний  smile

Остання редакція olegxter (2021-12-08 10:23:16)

Неактивний

#5 2021-12-08 12:05:17

vvr
Учасник
Зареєстрований: 2015-04-12
Повідомлень: 792

Re: Допомога у програмуванні

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

Неактивний

#6 2021-12-08 12:45:31

olegxter
Учасник
Зареєстрований: 2021-07-25
Повідомлень: 18

Re: Допомога у програмуванні

я жив і працював у Франції довго ))), в Solidworks працюю теж на en/fr - привичка))) а ще плюс лінь - коментарі зв скетчів заокеанських  smile

Неактивний

#7 2021-12-08 12:47:09

olegxter
Учасник
Зареєстрований: 2021-07-25
Повідомлень: 18

Re: Допомога у програмуванні

проєкт буде в тюбі - тому щоб не переписувати - коментарі англійською...

Неактивний

#8 2021-12-08 15:11:24

akapulko
Гість

Re: Допомога у програмуванні

Помилки легше шукати, а код простіше трактувати, якщо розбити задачу на підзадачі, у Вашому випадку це взагалі - просто необхідно. Почати можна з вимірювання RPM. В програмі використовується переривання  по передньому фронту (зміна сигналу з 0 на 1)  - "attachInterrupt(0, isr, RISING);", щоб спрацювало правильно треба підтримувати 0 у вихідному стані (без обертання). Вихід датчика треба "підтягнути" до 0 (підключити через резистор 10-20К), чи зроблено це?

#9 2021-12-08 20:31:48

г0сть
Гість

Re: Допомога у програмуванні

olegxter пише:

При компілюванні - з компа - видає помилку у формулі RPM; - з ноута - все нормально...

Значит комп умнее ноута.

#10 2021-12-08 21:38:15

olegxter
Учасник
Зареєстрований: 2021-07-25
Повідомлень: 18

Re: Допомога у програмуванні

big_smile

г0сть пише:
olegxter пише:

При компілюванні - з компа - видає помилку у формулі RPM; - з ноута - все нормально...

Значит комп умнее ноута.

big_smile  big_smile  big_smile

Неактивний

#11 2021-12-08 21:42:33

olegxter
Учасник
Зареєстрований: 2021-07-25
Повідомлень: 18

Re: Допомога у програмуванні

akapulko пише:

Помилки легше шукати, а код простіше трактувати, якщо розбити задачу на підзадачі, у Вашому випадку це взагалі - просто необхідно. Почати можна з вимірювання RPM. В програмі використовується переривання  по передньому фронту (зміна сигналу з 0 на 1)  - "attachInterrupt(0, isr, RISING);", щоб спрацювало правильно треба підтримувати 0 у вихідному стані (без обертання). Вихід датчика треба "підтягнути" до 0 (підключити через резистор 10-20К), чи зроблено це?

Доброго вечора.
Так підтягнутий... стоїть модуль KY-003

Неактивний

#12 2021-12-08 22:40:29

akapulko
Гість

Re: Допомога у програмуванні

Припустимо Ви праві, скільки імпульсів очікується на один оберт?

#13 2021-12-09 01:11:53

akapulko
Гість

Re: Допомога у програмуванні

Рекомендація: Прибрати модуль KY-003, використати "голий" сенсор (3144 чи подібний), між виводами Vcc та Out -> резистор 10-20k.

Код для перевірки (у pulsesPerRound підставити кіл-ть імпульсів на 1 повний оберт):

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()
{
  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);
}

#14 2021-12-09 09:18:30

olegxter
Учасник
Зареєстрований: 2021-07-25
Повідомлень: 18

Re: Допомога у програмуванні

akapulko пише:

Рекомендація: Прибрати модуль KY-003, використати "голий" сенсор (3144 чи подібний), між виводами Vcc та Out -> резистор 10-20k.

Код для перевірки (у pulsesPerRound підставити кіл-ть імпульсів на 1 повний оберт):

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()
{
  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);
}

Доброго дня.
Дякую за підказку за код.... трохи пізніше перевірю - відпишу

Неактивний

#15 2021-12-09 13:41:06

г0сть
Гість

Re: Допомога у програмуванні

akapulko пише:

Рекомендація: Прибрати модуль KY-003, використати "голий" сенсор (3144 чи подібний), між виводами Vcc та Out -> резистор 10-20k.

Если модуль "черный" то он и так голый, достаточно добавить резистор. Если красный - то смотреть к какому выходу подключен, аналоговый или цифровой.

akapulko пише:

Код для перевірки ...

Зачем такие сложности. Код ТС тоже вполне подойдет. Нужно только правильно разобраться с формулой.

#16 2021-12-09 14:12:07

akapulko
Гість

Re: Допомога у програмуванні

Так, дійсно, може спрацювати проста заміна рядка:
pinMode(SIG_pin, INPUT);         // pin signal Hall sensor
на рядок:
PORTD |= 1 << PD2;  // Internal Pull-up

Навіть без додаткового резистора може спрацювати.

#17 2021-12-09 18:25:54

Honey
Учасник
З Киев
Зареєстрований: 2020-09-26
Повідомлень: 96

Re: Допомога у програмуванні

akapulko пише:

Так, дійсно, може спрацювати проста заміна рядка:
pinMode(SIG_pin, INPUT);         // pin signal Hall sensor
на рядок:
PORTD |= 1 << PD2;  // Internal Pull-up

Тогда уж лучше заменить INPUT на INPUT_PULLUP, чтобы не было в коде мешанины.

Неактивний

#18 2021-12-09 19:24:28

г0сть
Гість

Re: Допомога у програмуванні

Honey пише:
akapulko пише:

Так, дійсно, може спрацювати проста заміна рядка:
pinMode(SIG_pin, INPUT);         // pin signal Hall sensor
на рядок:
PORTD |= 1 << PD2;  // Internal Pull-up

Тогда уж лучше заменить INPUT на INPUT_PULLUP, чтобы не было в коде мешанины.

Достаточно в формуле заменить 60*1000 на 60000 и не заниматься фигней

#19 2021-12-09 22:30:44

olegxter
Учасник
Зареєстрований: 2021-07-25
Повідомлень: 18

Re: Допомога у програмуванні

г0сть пише:
akapulko пише:

Рекомендація: Прибрати модуль KY-003, використати "голий" сенсор (3144 чи подібний), між виводами Vcc та Out -> резистор 10-20k.

Если модуль "черный" то он и так голый, достаточно добавить резистор. Если красный - то смотреть к какому выходу подключен, аналоговый или цифровой.

akapulko пише:

Код для перевірки ...

Зачем такие сложности. Код ТС тоже вполне подойдет. Нужно только правильно разобраться с формулой.

Доброго вечора.
Модуль - чорний, датчик 3144EUA-S, резистор 680 Ом та лед індикатор,без поля - на виході HIGH. при набллиженні магніта до датчика - загоряється лед

Остання редакція olegxter (2021-12-09 23:52:33)

Неактивний

#20 2021-12-09 23:04:28

olegxter
Учасник
Зареєстрований: 2021-07-25
Повідомлень: 18

Re: Допомога у програмуванні

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 байтів.
Повідомлення про помилку

Неактивний

#21 2021-12-09 23:29:48

olegxter
Учасник
Зареєстрований: 2021-07-25
Повідомлень: 18

Re: Допомога у програмуванні

г0сть пише:
Honey пише:
akapulko пише:

Так, дійсно, може спрацювати проста заміна рядка:
pinMode(SIG_pin, INPUT);         // pin signal Hall sensor
на рядок:
PORTD |= 1 << PD2;  // Internal Pull-up

Тогда уж лучше заменить INPUT на INPUT_PULLUP, чтобы не было в коде мешанины.

Достаточно в формуле заменить 60*1000 на 60000 и не заниматься фигней

Змінив рядок, змінив формулу - стало значно краще  hmm  RPM=0 тільки деколи проскакує  = 30861  sad  sad  sad

Неактивний

#22 2021-12-10 00:54:32

akapulko
Гість

Re: Допомога у програмуванні

Ще раз, я дав робочий (апробований з сенсором 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В) до однойменного вивода на платі.

#23 2021-12-10 01:18:32

г0сть
Гість

Re: Допомога у програмуванні

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 і наступну строку закоментувати/видалити

#24 2021-12-10 01:22:15

г0сть
Гість

Re: Допомога у програмуванні

olegxter пише:

без поля - на виході HIGH.

У такому разі RISING треба замінити на FALLING

#25 2021-12-10 09:28:19

olegxter
Учасник
Зареєстрований: 2021-07-25
Повідомлень: 18

Re: Допомога у програмуванні

akapulko пише:

Ще раз, я дав робочий (апробований з сенсором 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 ...
Але то наступний крок.

Остання редакція olegxter (2021-12-10 09:44:15)

Неактивний

Швидке повідомлення

Введіть повідомлення і натисніть Надіслати

Підвал форуму