Прикрутить onewire интерфейс к аналоговму пину

Тема в разделе "Arduino & Shields", создана пользователем Nekto_nikto, 10 сен 2020.

  1. Nekto_nikto

    Nekto_nikto Гик

    Доброго времени суток.
    Есть необходимость прикрутить OneWire интерфейс к аналоговому пину, стандартная библиотека его не воспринимает. Хочется повесить на этот пин датчик температуры.
    Может есть какие то специальные библиотеки под аналоговые пины?
    Стандартная одноименная библиотека OneWire работает только с цифровыми пинами.
     
  2. b707

    b707 Гуру

    какому именно пину (номер), на каком МК?
    Например на Уно аналоговые пины А0-А5 являются одновременно и цифровыми. нет никакх проблем запустить на них OneWire
     
  3. Nekto_nikto

    Nekto_nikto Гик

    МК ATMega2560
    порт A3
    То что все они являются цифровыми я тоже понимаю, НО например такая конструкция для инициализации не прокатывает
    Код (C++):
    DDRA=DDRA&0b11110111;
    PORTA=PORTA|0b00001000;
    PINA=PINA&0b11110111;
    Делал по странице №69 даташита на мегу
    А если просто сделать так:
    Код (C++):
    pinMode(3, OUTPUT);     // Так светодиод горит
    analogWrite(3, 255);
    while(true)
    {
    delay(500);
    digitalWrite(3, HIGH);  // Мигает
    delay(500);
    digitalWrite(3, LOW);
    }
    то мигает, а если не проставить analogWrite(3, 255); то при первом же вызове digitalWrite уходит в ноль - проверял светодиодом на пине.
     
    Последнее редактирование: 10 сен 2020
  4. asam

    asam Гик

    Смешались в кучу кони, люди...
    Вы про какие номера портов говорите? МК или ардуино мега?
    pinMode(3,,,) , digitalWrite(3) Это D3 arduino mega или PE5 МК. Поэтому естественно первый код не прокатывает.
    analogWrite(3, 255) это D57 arduino mega или PF3 MK
     
  5. b707

    b707 Гуру

    я б вообще запретил прямое обращение к регистрам тем, кто до того не программировал на ардуине года два...
     
    Daniil нравится это.
  6. Nekto_nikto

    Nekto_nikto Гик

    Ну да - не подумал, как то обозначить от чего порт. A3 это 3 пин порта A меги 2560, он же 3 в дуньке.
    Вот собственно распиновка из прошивки Marlin
    Код (C++):
    /**
    * Pin mapping for the 1280 and 2560
    *
    *   1280     22 23 24 25 26 27 28 29 53 52 51 50 10 11 12 13 37 36 35 34 33 32 31 30 21 20 19 18 81 82 83 38 00 01 78 05 02 03 79 80 54 55 56 57 58 59 60 61 41 40 39 71 70 04 17 16 84 06 07 08 09 85 15 14 72 73 75 76 77 74 62 63 64 65 66 67 68 69 49 48 47 46 45 44 43 42
    *   Port     A0 A1 A2 A3 A4 A5 A6 A7 B0 B1 B2 B3 B4 B5 B6 B7 C0 C1 C2 C3 C4 C5 C6 C7 D0 D1 D2 D3 D4 D5 D6 D7 E0 E1 E2 E3 E4 E5 E6 E7 F0 F1 F2 F3 F4 F5 F6 F7 G0 G1 G2 G3 G4 G5 H0 H1 H2 H3 H4 H5 H6 H7 J0 J1 J2 J3 J4 J5 J6 J7 K0 K1 K2 K3 K4 K5 K6 K7 L0 L1 L2 L3 L4 L5 L6 L7
    *   Marlin   00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
    */

    откуда видно, что 3 порт в дуньке, равно как и а марлине это 3 пин порта A МК с 25 порядковым номером.

    Просто есть плата от 3D принтера, хочу ее приспособить под другие нужды, т.к. большая часть периферии там уже встроена.
     
  7. asam

    asam Гик

    Даже по приведенной таблице Ардуиновский порт 03 это порт Е5 у меги 2560
     
  8. Nekto_nikto

    Nekto_nikto Гик

    Я так не думаю, потому что в том же марлине, когда названиям периферии присваиваются номера пинов, присваиваются именно нижние, => это номера пинов и из arduino среды.
     
  9. asam

    asam Гик

    Ну думайте что хотите, просто потом не удивляейтесь что оно не работает.
     
  10. Nekto_nikto

    Nekto_nikto Гик

    Признаю - был неправ
    https://www.arduino.cc/en/Hacking/PinMapping2560
    [​IMG]
    Но как тогда объяснить тот факт, что 3 пин ведет себя как аналоговый и если подать команду digitalWrite, независимо от того высокий вы уровень подадите или низкий, переключается в низкий логический уровень. А если перед этим прописать analogWrite(3,255), то тогда с ним можно работать командами digitalWrite, НО при этом oneWire интерфейс с ним попрежнему работать не в состоянии и датчик подключенный к этому пину стабильно выдает ноль, независимо от того какая на нем температура.
     
    KindMan нравится это.
  11. akl

    akl Гуру

    если имеется в виду PE5 (7я нога микросхемы), то это вообще не аналоговый пин, т.к. аналоговыми называеются ноги к которым может подключиться вход АЦП и к analogWrite это не имеет отношения, а PE5 это обычная цифровая нога с возможностю вывода ШИМ (analogWrite это не "аналоговый выход" - это тупо ШИМ)

    кстати analogWrite(3,255) тупо прописывает digitalWrite(3, HIGH), который уже в свою очередь если надо отключит ногу от таймера и т.д.

    если же имеется в виду аналоговый пин 3, то есть PF3, то в цифровом виде это должен быть пин 57, по крайней мере если верить внутренностям ардуино

    Код (C++):
    #define PIN_A0   (54)
    #define PIN_A1   (55)
    #define PIN_A2   (56)
    #define PIN_A3   (57)
    #define PIN_A4   (58)
    #define PIN_A5   (59)
    #define PIN_A6   (60)
    #define PIN_A7   (61)
    #define PIN_A8   (62)
    #define PIN_A9   (63)
    #define PIN_A10  (64)
    #define PIN_A11  (65)
    #define PIN_A12  (66)
    #define PIN_A13  (67)
    #define PIN_A14  (68)
    #define PIN_A15  (69)

    static const uint8_t A0 = PIN_A0;
    static const uint8_t A1 = PIN_A1;
    static const uint8_t A2 = PIN_A2;
    static const uint8_t A3 = PIN_A3;
    static const uint8_t A4 = PIN_A4;
    static const uint8_t A5 = PIN_A5;
    static const uint8_t A6 = PIN_A6;
    static const uint8_t A7 = PIN_A7;
    static const uint8_t A8 = PIN_A8;
    static const uint8_t A9 = PIN_A9;
    static const uint8_t A10 = PIN_A10;
    static const uint8_t A11 = PIN_A11;
    static const uint8_t A12 = PIN_A12;
    static const uint8_t A13 = PIN_A13;
    static const uint8_t A14 = PIN_A14;
    static const uint8_t A15 = PIN_A15;
     
  12. Nekto_nikto

    Nekto_nikto Гик

    Судя по распиновке речь идет именно про PE5, он же 3 пин arduino, вчера сидел с платкой, и подключенным к этому выходу светодиодом, чтоб выяснить всетаки, какой у него номер. Для этого написал простенький скетч, который раз в 5 секунд подключается к следующему пину, начиная с 1 и выполняет на нем код, который должен привести к миганию светодиода, попутно выводя в монитор порта номер пина с которым он сейчас работает.
    И ситуация была такая, до того как скетч добирался до 3 пина светодиод чуть горел, после того как скетч добрался до 3 светодиод тут же тух, а не мигал как должен был в течении 4 секунд.
    Как то так.
     
  13. akl

    akl Гуру

    либо скетч кривоват либо нога микросхемы поломана, либо контакт плохой. не знаю как еще можно это объяснить
    ибо
    Код (C++):
    void analogWrite(uint8_t pin, int val)
    {
        // We need to make sure the PWM output is enabled for those pins
        // that support it, as we turn it off when digitally reading or
        // writing with them.  Also, make sure the pin is in output mode
        // for consistenty with Wiring, which doesn't require a pinMode
        // call for the analog output pins.
        pinMode(pin, OUTPUT);
        if (val == 0)
        {
            digitalWrite(pin, LOW);
        }
        else if (val == 255)
        {
            digitalWrite(pin, HIGH);
        }
        else
        {
            switch(digitalPinToTimer(pin))
            {
                // XXX fix needed for atmega8
                #if defined(TCCR0) && defined(COM00) && !defined(__AVR_ATmega8__)
                case TIMER0A:
                    // connect pwm to pin on timer 0
                    sbi(TCCR0, COM00);
                    OCR0 = val; // set pwm duty
                    break;
                #endif

                #if defined(TCCR0A) && defined(COM0A1)
                case TIMER0A:
                    // connect pwm to pin on timer 0, channel A
                    sbi(TCCR0A, COM0A1);
                    OCR0A = val; // set pwm duty
                    break;
                #endif

                #if defined(TCCR0A) && defined(COM0B1)
                case TIMER0B:
                    // connect pwm to pin on timer 0, channel B
                    sbi(TCCR0A, COM0B1);
                    OCR0B = val; // set pwm duty
                    break;
                #endif

                #if defined(TCCR1A) && defined(COM1A1)
                case TIMER1A:
                    // connect pwm to pin on timer 1, channel A
                    sbi(TCCR1A, COM1A1);
                    OCR1A = val; // set pwm duty
                    break;
                #endif

                #if defined(TCCR1A) && defined(COM1B1)
                case TIMER1B:
                    // connect pwm to pin on timer 1, channel B
                    sbi(TCCR1A, COM1B1);
                    OCR1B = val; // set pwm duty
                    break;
                #endif

                #if defined(TCCR1A) && defined(COM1C1)
                case TIMER1C:
                    // connect pwm to pin on timer 1, channel B
                    sbi(TCCR1A, COM1C1);
                    OCR1C = val; // set pwm duty
                    break;
                #endif

                #if defined(TCCR2) && defined(COM21)
                case TIMER2:
                    // connect pwm to pin on timer 2
                    sbi(TCCR2, COM21);
                    OCR2 = val; // set pwm duty
                    break;
                #endif

                #if defined(TCCR2A) && defined(COM2A1)
                case TIMER2A:
                    // connect pwm to pin on timer 2, channel A
                    sbi(TCCR2A, COM2A1);
                    OCR2A = val; // set pwm duty
                    break;
                #endif

                #if defined(TCCR2A) && defined(COM2B1)
                case TIMER2B:
                    // connect pwm to pin on timer 2, channel B
                    sbi(TCCR2A, COM2B1);
                    OCR2B = val; // set pwm duty
                    break;
                #endif

                #if defined(TCCR3A) && defined(COM3A1)
                case TIMER3A:
                    // connect pwm to pin on timer 3, channel A
                    sbi(TCCR3A, COM3A1);
                    OCR3A = val; // set pwm duty
                    break;
                #endif

                #if defined(TCCR3A) && defined(COM3B1)
                case TIMER3B:
                    // connect pwm to pin on timer 3, channel B
                    sbi(TCCR3A, COM3B1);
                    OCR3B = val; // set pwm duty
                    break;
                #endif

                #if defined(TCCR3A) && defined(COM3C1)
                case TIMER3C:
                    // connect pwm to pin on timer 3, channel C
                    sbi(TCCR3A, COM3C1);
                    OCR3C = val; // set pwm duty
                    break;
                #endif

                #if defined(TCCR4A)
                case TIMER4A:
                    //connect pwm to pin on timer 4, channel A
                    sbi(TCCR4A, COM4A1);
                    #if defined(COM4A0)        // only used on 32U4
                    cbi(TCCR4A, COM4A0);
                    #endif
                    OCR4A = val;    // set pwm duty
                    break;
                #endif
             
                #if defined(TCCR4A) && defined(COM4B1)
                case TIMER4B:
                    // connect pwm to pin on timer 4, channel B
                    sbi(TCCR4A, COM4B1);
                    OCR4B = val; // set pwm duty
                    break;
                #endif

                #if defined(TCCR4A) && defined(COM4C1)
                case TIMER4C:
                    // connect pwm to pin on timer 4, channel C
                    sbi(TCCR4A, COM4C1);
                    OCR4C = val; // set pwm duty
                    break;
                #endif
                 
                #if defined(TCCR4C) && defined(COM4D1)
                case TIMER4D:              
                    // connect pwm to pin on timer 4, channel D
                    sbi(TCCR4C, COM4D1);
                    #if defined(COM4D0)        // only used on 32U4
                    cbi(TCCR4C, COM4D0);
                    #endif
                    OCR4D = val;    // set pwm duty
                    break;
                #endif

                             
                #if defined(TCCR5A) && defined(COM5A1)
                case TIMER5A:
                    // connect pwm to pin on timer 5, channel A
                    sbi(TCCR5A, COM5A1);
                    OCR5A = val; // set pwm duty
                    break;
                #endif

                #if defined(TCCR5A) && defined(COM5B1)
                case TIMER5B:
                    // connect pwm to pin on timer 5, channel B
                    sbi(TCCR5A, COM5B1);
                    OCR5B = val; // set pwm duty
                    break;
                #endif

                #if defined(TCCR5A) && defined(COM5C1)
                case TIMER5C:
                    // connect pwm to pin on timer 5, channel C
                    sbi(TCCR5A, COM5C1);
                    OCR5C = val; // set pwm duty
                    break;
                #endif

                case NOT_ON_TIMER:
                default:
                    if (val < 128) {
                        digitalWrite(pin, LOW);
                    } else {
                        digitalWrite(pin, HIGH);
                    }
            }
        }
    }
    может просто pinMode(3, OUTPUT); не прописан? аналогВрайт как раз это делает
     
  14. Nekto_nikto

    Nekto_nikto Гик

    Вот сама програмка, которой вчера выяснял номер пина:
    Код (C++):
    String S="";              // Переменная передаваемая через COM порт
    int Pin=0;

    long lastUpdateTime = 0;  // Переменная для хранения времени последнего считывания с датчика
    const int TEMP_UPDATE_TIME = 5000; // Определяем периодичность проверок

    void setup() {
      // put your setup code here, to run once:

    delay(5000);
    Serial.begin(9600); // подключаем последовательный порт
    }





    void loop() {
    // put your main code here, to run repeatedly:
    while(Pin<101)
      {
      if (millis() - lastUpdateTime > TEMP_UPDATE_TIME)
        {
        lastUpdateTime = millis();
        Pin++;
        S="PIN_NUMBER="+String(Pin);
        Serial.println(S);
        pinMode(Pin, OUTPUT);
        for(int i=0;i++;i<=8)
          {
          digitalWrite(Pin, LOW);
          delay(500);
          digitalWrite(Pin, HIGH);
          delay(500);
          }
        }
      }
    Serial.println("PINS OUT OF NUMBER");
    }
     
  15. akl

    akl Гуру

    а светодиод как подключен?

    а еще мне кажется что настраивать ногу RX0 на выход - не лучшая идея. но это не точно
     
    Andrey12 нравится это.
  16. Nekto_nikto

    Nekto_nikto Гик

    Беда в том, что там еще 4 ноги так же себя ведут, да и плюс ко всему 2 нога ,которая RX0 отрабатвает норально, на ней по замыслу другой такой же датчик температуры висит и работает нормально.
     
  17. akl

    akl Гуру

    так же себя ведут со светодиодом? а светодиод как подключен? через резистор? наземлю или на питание? если на питание то на какое именно?
    еще 4 ноги это тот же порт E?

    нормально на ноге RX0 работает тот же самый датчик, или другой датчик?
     
  18. a1000

    a1000 Гуру

    Так вы пытаетесь поморгать с подключенной периферией?
     
  19. Nekto_nikto

    Nekto_nikto Гик

    akl:
    ведут себя также, светодиод подключен через резистор
    светодиод: GND VCC
    плата: GND Pin3
    На плате разъемы с 3 пинами под датчики, вот к этим пинам и подключается.
    14 15 18 19
    PH2 PH3 PH6 PB0
    в общем все пины цифровые, но нормально отрабатывает только 2.
    Датчик один и тот же, сначала было 2, но потом как выяснилось китайцы с али на один датчик прокинули, поэтому проверял с одним и тем же.

    a1000:
    нет периферия выключена, подключен только светодиод и USB от ПК.
     
  20. akl

    akl Гуру

    тащемта, на RX0 TX0 всегда подключена периферия в виде юсб-адаптера.

    что за плата такая с разъемами? может дело в этих разъемах?