Нерабочий ШИМ?

Drambynik
Drambynik аватар
Offline
Зарегистрирован: 14.05.2016

Очень странно ведут себя выводы ШИМ на ардуине уно. От 0 до 254 напряжение на выводе плавно регулируется от 0 до 0,1 В. При 255 подскакивает до 5 В. Что то с платой?

Вот что осциллограф показывает:

T.Rook
Offline
Зарегистрирован: 05.03.2016

Код приложите, для начала на номера пинов посмотрим.

Drambynik
Drambynik аватар
Offline
Зарегистрирован: 14.05.2016
#include <TM74HC595Display.h>
#include <TimerOne.h>

int SCLK = 7;
int RCLK = 6;
int DIO = 5;

int pinA = 3;  // номер вывода, подключенный к CLK енкодера
int pinB = 4;  // номер вывода контроллера, подключенный к DT енкодера
int encoderPosCount = 0; 
int pinALast;  
int aVal;
boolean bCW;

TM74HC595Display disp(SCLK, RCLK, DIO);
unsigned char LED_0F[30];

void timerIsr()
{
  disp.timerIsr();
}

void setup() {
  LED_0F[0] = 0xC0; //0
  LED_0F[1] = 0xF9; //1
  LED_0F[2] = 0xA4; //2
  LED_0F[3] = 0xB0; //3
  LED_0F[4] = 0x99; //4
  LED_0F[5] = 0x92; //5
  LED_0F[6] = 0x82; //6
  LED_0F[7] = 0xF8; //7
  LED_0F[8] = 0x80; //8
  LED_0F[9] = 0x90; //9
  LED_0F[10] = 0x88; //A
  LED_0F[11] = 0x83; //b
  LED_0F[12] = 0xC6; //C
  LED_0F[13] = 0xA1; //d
  LED_0F[14] = 0x86; //E
  LED_0F[15] = 0x8E; //F
  LED_0F[16] = 0xC2; //G
  LED_0F[17] = 0x89; //H
  LED_0F[18] = 0xF9; //I
  LED_0F[19] = 0xF1; //J
  LED_0F[20] = 0xC3; //L
  LED_0F[21] = 0xA9; //n
  LED_0F[22] = 0xC0; //O
  LED_0F[23] = 0x8C; //P
  LED_0F[24] = 0x98; //q
  LED_0F[25] = 0x92; //S
  LED_0F[26] = 0xC1; //U
  LED_0F[27] = 0x91; //Y
  LED_0F[28] = 0xFE; //hight -
  LED_0F[29] = 0b1111111;

  Timer1.initialize(1500); // set a timer of length 1500
  Timer1.attachInterrupt(timerIsr); // attach the service routine here
  
  pinMode (pinA,INPUT);
  pinMode (pinB,INPUT);
  /* Считываем значение на выводе A и запоминаем его как последнее значение на этом выводе */
  pinALast = digitalRead(pinA);
  Serial.begin (9600);
  pinMode(10, OUTPUT);
}

void loop() {  
//disp.set(LED_0F[29], 0);
   aVal = digitalRead(pinA);
   if (aVal != pinALast){ // проверка на изменение значения на выводе А по сравнению с предыдущим запомненным, что означает, что вал повернулся
     // а чтобы определить направление вращения, нам понадобится вывод В.
     if (digitalRead(pinB) != aVal) {  // Если вывод A изменился первым - вращение по часовой стрелке
       encoderPosCount ++;
       disp.clear();
       bCW = true;
     } else {// иначе B изменил свое состояние первым - вращение против часовой стрелки
       bCW = false;
       encoderPosCount--;
       disp.clear();
     }
        if (encoderPosCount>255){
    encoderPosCount=255;
    }
    if(encoderPosCount<=0){
       encoderPosCount=0;
      }
     disp.digit4(encoderPosCount);     
     Serial.print("VAl: ");
     Serial.println(encoderPosCount);
     analogWrite(10, encoderPosCount);
   } 
   
   pinALast = aVal;
       
}

Пробовал 9, 10, 11 ноги

T.Rook
Offline
Зарегистрирован: 05.03.2016

А зачем Вам  #include <TimerOne.h>, если Вы ивсе равно используете стандартный analogWrite, а не pwm из Timer1?

а.. сорри проглядел. сейчас вчитаюсь более внимательно.

Drambynik
Drambynik аватар
Offline
Зарегистрирован: 14.05.2016

T.Rook пишет:

А зачем Вам  #include <TimerOne.h>, если Вы ивсе равно используете стандартный analogWrite, а не pwm из Timer1?

TimerOne.h для динамической индикации на семисегменте.

T.Rook
Offline
Зарегистрирован: 05.03.2016

1. На всякий случай переспрошу: на 3,5,6,11 точно не работает?

2. А Timer1.pwm (9, encoderPosCount); не пробовали (не забыв что макс=1024, а не 255)?

Drambynik
Drambynik аватар
Offline
Зарегистрирован: 14.05.2016

Я и не знал про функцию pwm в Timer1. Только что попробовал. Работает Timer1.pwm (9, encoderPosCount);

А почему стандартная функция не работает?

T.Rook
Offline
Зарегистрирован: 05.03.2016

Потому что analogWrite для 9,10 пинов на Уне использует первый таймер который в Вашем скетче используется библиотекой. Наверное так :))

Drambynik
Drambynik аватар
Offline
Зарегистрирован: 14.05.2016

Спасибо. Проблема решена.