ATtiny13A 101 применение

bodriy2014
bodriy2014 аватар
Offline
Зарегистрирован: 12.05.2015

dimax пишет:

bodriy2014,  плавненько?.. скачет рывками, и  нелинейно. Хотя наверное зверю это неважно) Но лучше всё таки через DDS

Спасибо за ссылку,

я и не видел оказывается по этому ТЗ целая ветка была.

Век живу век учусь!)

kirex
Offline
Зарегистрирован: 17.01.2017

dimax пишет:

Но лучше всё таки через DDS

Я извиняюсь, куда в вашем коде вставить мигание светодиода?

1 #define ledon PORTB |= 1<<PB1
2 #define ledoff PORTB &= ~1<<PB1
3  
4 ledon;
5 _delay_ms(500);
6 ledoff;

Т.е. чтоб светодиод мигал один раз в начале каждого цикла.

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

kirex, дык куда Вам нужно туда и вставляйте. Наиболее очевидный вариант -после большой паузы.

Danis 2008
Offline
Зарегистрирован: 08.02.2017

помогите пожалуйста, как создать календарь на базе ардуино?

shakh
Offline
Зарегистрирован: 09.02.2017

Здравствуйте Уважаемые форумчане.

Помогите разобраться. При компиляции примера работы с EEPROM из поста #2,

#include <avr/eeprom.h> // не забываем подключить
int Address = 0;
byte Data = 255; // для экономии рекомендую использовать тип byte(диапазон 0-255)
void setup()
{
}
void loop()
{
  EEPROM_read(Address);
  EEPROM_write(Address, Data);
}
void EEPROM_write(unsigned int uiAddress, unsigned char ucData)
{
  while(EECR & (1<<EEWE)); /*Ждать завершения предыдущей записи*/
  EEAR = uiAddress; /*Проинициализировать регистры*/
  EEDR = ucData;
  EECR |= (1<<EEMWE); /*Установить флаг EEMWE*/
  EECR |= (1<<EEWE); /*Начать запись в EEPROM*/
}
unsigned char EEPROM_read(unsigned int uiAddress)
{
  while(EECR & (1<<EEWE)); /*Ждать завершения предыдущей записи*/
  EEAR = uiAddress; /* Проинициализировать регистр адреса*/
  EECR |= (1<<EERE); /*Выполнить чтение*/
  return EEDR;
}

выдается ошибка "'EEWE' was not declared in this scope".  

Arduino: 1.6.7 (Windows 7), Плата:"ATtiny13 (ATtiny13a), 1.2 MHz"

Что я делаю не так? 

 
Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

shakh пишет:

При компиляции примера работы с EEPROM из поста #2,

Эм... Не знаю, откуда автор кода их взял, но по даташиту Attint13A в регистре EECR нет битов EEWE и EEMWE. 

shakh
Offline
Зарегистрирован: 09.02.2017

Jeka_M пишет:

в регистре EECR нет битов EEWE и EEMWE. 

Спасибо за наводку! Действительно, эти флаги называются EEPE и EEMPE. После замены все работает:

#include <avr/eeprom.h>
int Address = 0;
byte Data = 255;
void setup()
{
}
void loop()
{
  EEPROM_read(Address);
  EEPROM_write(Address, Data);
}
void EEPROM_write(unsigned int uiAddress, unsigned char ucData)
{
  while(EECR & (1<<EEPE)); 
  EEAR = uiAddress; 
  EEDR = ucData;
  EECR |= (1<<EEMPE); 
  EECR |= (1<<EEPE); 
}
unsigned char EEPROM_read(unsigned int uiAddress)
{
  while(EECR & (1<<EEPE)); 
  EEAR = uiAddress; 
  EECR |= (1<<EERE);
  return EEDR;
}

 

Dragon_Kursk
Offline
Зарегистрирован: 01.09.2015

Подскажите как загрузить этот код в Attiny13a


int led = 0;   выход на мотор
int j=0;
int i=0;
const int buttonPin = 2;    переменный резистор 
int buttonState = 2;        
 
void setup()
{
  pinMode(led, OUTPUT);
  pinMode(buttonPin, INPUT); 
}
 
void loop()
{
  
  buttonState = analogRead(buttonPin);
   
  if ((buttonState-i)/abs(buttonState-i)>0)
     {
      i++;
    }
    if ((buttonState-i)/abs(buttonState-i)<0) 
    {
      i-=3;
    }  
j=map(i,0,1023,0,255);
if (j<9) j=0;
analogWrite(led,j);
        delay(5);   
}

 

 

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Установить в Arduino IDE поддержку Attiny13a, скомпилировать, загрузить с помощью программатора (USBasp) или другой ардуины со скетчем эмулятора программатор (ArduinoISP)

Dragon_Kursk
Offline
Зарегистрирован: 01.09.2015

Jeka_M пишет:

Установить в Arduino IDE поддержку Attiny13a, скомпилировать, загрузить с помощью программатора (USBasp) или другой ардуины со скетчем эмулятора программатор (ArduinoISP)

пробовал не влазиим 

Dragon_Kursk
Offline
Зарегистрирован: 01.09.2015

в том виде как написано в ардуино весит все 1264 байта, а в микре всего 1020 (((

bodriy2014
bodriy2014 аватар
Offline
Зарегистрирован: 12.05.2015

Dragon_Kursk пишет:

Подскажите как загрузить этот код в Attiny13a


int led = 0;   выход на мотор
int j=0;
int i=0;
const int buttonPin = 2;    переменный резистор 
int buttonState = 2;        
 
void setup()
{
  pinMode(led, OUTPUT);
  pinMode(buttonPin, INPUT); 
}
 
void loop()
{
  
  buttonState = analogRead(buttonPin);
   
  if ((buttonState-i)/abs(buttonState-i)>0)
     {
      i++;
    }
    if ((buttonState-i)/abs(buttonState-i)<0) 
    {
      i-=3;
    }  
j=map(i,0,1023,0,255);
if (j<9) j=0;
analogWrite(led,j);
        delay(5);   
}

А что он должен делать?

можно же проще это написать.

Похоже что он должен менять ШИМ в зависимости от поворота потенциометра.

Dragon_Kursk
Offline
Зарегистрирован: 01.09.2015

Да изменение шима но и плавное нарастание до заданного значения резистором, и так же плавный спад до нулевого значения, типа защита от резкого разгона двигателя и плавный останов.

bodriy2014
bodriy2014 аватар
Offline
Зарегистрирован: 12.05.2015

Dragon_Kursk пишет:
Да изменение шима но и плавное нарастание до заданного значения резистором, и так же плавный спад до нулевого значения, типа защита от резкого разгона двигателя и плавный останов.

То есть вы резистором устанавливаете мощность,  но набирать он ее должен плавно и убавлять так- же плавно?

Это можно проще реализовать ище и место в тини13 останется.

Dragon_Kursk
Offline
Зарегистрирован: 01.09.2015

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

Dragon_Kursk
Offline
Зарегистрирован: 01.09.2015

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

bodriy2014
bodriy2014 аватар
Offline
Зарегистрирован: 12.05.2015

Dragon_Kursk пишет:
Да, это устройство для детского электромобиля, на педальке резистор, плавный разгон, и плавное торможение только спад шима быстрей чем разгон. И плавное нарастание шима незасимо от того как резко нажимают на педаль. Все это изначально делалось под атмегу 328 а перенести на тинку не получилось.

Вот код.

Коменты для вас трудился писал.

Пины можно менять, но незабываем что у тини13 всего две ноги ШИМ.

512 bytes можно и меньше сделать, но зачем)))

#define otklik 10 //скорость отклика на поворот потенциометра
#define input PB2  //пин потенциометра
#define motor PB1  //пин мотора
int PWM = 0;
int val = 0;
void setup() {
  pinMode(input, INPUT);
  pinMode(motor, OUTPUT);
}

void loop() {
  val = analogRead(input) / 4;   //читаем потенциометр
  if (val > PWM) {               //если он больше ШИМ увеличиваем 
    PWM++;
  }
  if (val < PWM) {              //если он меньше ШИМ уменьшаем
    PWM=PWM-2;                  //спад быстрее чем разгон
  }
  analogWrite(motor, PWM);
  delay(otklik);               //скорость отклика на изменение скорости
}

 

Dragon_Kursk
Offline
Зарегистрирован: 01.09.2015

Спасибо завтра опробую,так как все осталось на работе. И отпишусь. )))

Dragon_Kursk
Offline
Зарегистрирован: 01.09.2015

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

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

#define otklik 10 //скорость отклика на поворот потенциометра
#define input PB1  //пин потенциометра
#define motor PB0  //пин мотора
int PWM = 0;
int val = 0;
void setup() {
  pinMode(input, INPUT);
  pinMode(motor, OUTPUT);
}
 
void loop() {
  val = analogRead(input) / 40;   //читаем потенциометр
  val=val*10;
  if (val > PWM) {               //если он больше ШИМ увеличиваем
    PWM++;
  }
  if (val < PWM) {              //если он меньше ШИМ уменьшаем
    PWM=PWM-2;                  //спад быстрее чем разгон
  }
  if (PWM<0) PWM=0;
  analogWrite(motor, PWM);
  delay(otklik);               //скорость отклика на изменение скорости
}

 

porese
Offline
Зарегистрирован: 20.03.2017

Так около 150 байт сбережем

#include <avr/io.h>
#include <util/delay.h>

#define otklik 10   //скорость отклика на поворот потенциометра
#define input PB1   //пин потенциометра
#define motor PB0   //пин мотора

int main() {
  int PWM = 0;
  unsigned int val = 0;
  
  pinMode(input, INPUT);
  pinMode(motor, OUTPUT);
  while (1) {
    val = (analogRead(input) / 40) * 10;              //читаем потенциометр
    if (val > PWM) PWM++;                             //если он больше ШИМ увеличиваем
    if (val < PWM) if((PWM = PWM - 2) < 0) PWM = 0;   //если он меньше ШИМ уменьшаем спад быстрее чем разгон
    analogWrite(motor, PWM);
    _delay_ms(otklik);                                //скорость отклика на изменение скорости
  }
}

 

Alex_Mirko
Alex_Mirko аватар
Offline
Зарегистрирован: 16.05.2016

Здравствуйте форумчане. Я самоучка делитант, так что строго не судите)

Накидал схему led светильника в машину с плавным розжигом и управлением через оптопару.

Вот код

#define pwmLed 0
#define IR_LED 2
#define DOORS 3
#define IR_D 2

boolean stateLed = false;
boolean stateDoor = false;

void setup() {
  analogWrite(pwmLed, 0);
  DDRB &= ~(1 << 3); //устанавливаем РВ3 на вход
  DDRB |= (1 << 2); //устанавливаем РВ2 на выход
  PORTB &= ~(1 << 2); //устанавливаем на РВ2 низкий уровень

}

void OFF_Led() { //функция плавного выключения

  stateLed = false; //флаг состояния фонаря выкл.

  for (unsigned int i = 255; i >= 1; i--) {

    analogWrite(pwmLed, (i * i) / 255);

    delay(5);
  }
}

void ON_Led() { //функция плавного включения

  stateLed = true; //флаг состояния фонаря вкл.

  for (unsigned int i = 0; i <= 255; i++) {

    analogWrite(pwmLed, (i * i) / 255);

    delay(10);
  }
}

bool IR_dt() { //проверка на наличие препятствия перед оптопарой
  int ReadIR = analogRead_C(IR_D);
  PORTB |= (1 << 2); //устанавливаем на РВ2 высокий уровень, включаем ИК диод
  delay(1);
  ReadIR = ReadIR - analogRead_C(IR_D);
  PORTB &= ~(1 << 2); //устанавливаем на РВ2 низкий уровень, выключаем ИК диод
  return ReadIR > 300;
}

unsigned int analogRead_C(byte channel) {
  ADMUX = channel;
  ADCSRA |= 1 << ADEN;
  ADCSRA |= 1 << ADSC;
  while (!(ADCSRA & (1 << ADIF)));
  ADCSRA |= 1 << ADIF;
  byte low  = ADCL;
  byte high = ADCH;
  ADCSRA &= ~(1 << ADEN);
  return (high << 8) | low;
}

void loop() {

  if (!(PINB & (1 << PINB3))) { //проверка состояния двери
    if (!stateDoor) { //если была закрыта и ее открыли
      stateDoor = true; //меняем ее статус на открыто
      if (!stateLed) { //если фонарь выключен, включаем
        ON_Led();
      }
    }
  }
  else {//дверь закрыта
    delay(50);
    if (PINB & (1 << PINB3)) { //защита от помех
      if (stateDoor) { //если была открыта и ее закрыли
        stateDoor = false; //меняем статус на закрыто
        if (stateLed) { //если фонарь включен, выключаем
          OFF_Led();
          delay(2000);
        }
      }
    }
  }

  if (IR_dt()) { //проверка на наличие препятствия

    delay(100);
    boolean up = true; //флаг от повторного срабатывания

    while (true) {

      if (up) {
        if (stateLed) OFF_Led(); //если фонарь включен, выключаем
        else ON_Led(); //если фонарь выключен, включаем
        up = false;
      }

      if (!IR_dt()) { //при отсутствии препятствия выходим из цикла
        break;
      }
    }
    delay(200);
  }
}

Проблема в том что код работает не корректно, во время работы МК не учитывает некоторые флаги. Тиньки брал с Китая, может быть проблема в них?

bodriy2014
bodriy2014 аватар
Offline
Зарегистрирован: 12.05.2015

Alex_Mirko пишет:

.....

Проблема в том что код работает не корректно, во время работы МК не учитывает некоторые флаги. Тиньки брал с Китая, может быть проблема в них?

Очень точное описание проблемы!)

Кстати они с час все с Китая.

Alex_Mirko
Alex_Mirko аватар
Offline
Зарегистрирован: 16.05.2016
#define pwmLed 0
#define IR_LED 2
#define DOORS 3
#define IR_D 2

boolean stateLed = false;
boolean stateDoor = false;

void setup() {
  analogWrite(pwmLed, 0);
  DDRB &= ~(1 << 3); //устанавливаем РВ3 на вход
  DDRB |= (1 << 2); //устанавливаем РВ2 на выход
  PORTB &= ~(1 << 2); //устанавливаем на РВ2 низкий уровень

}

void OFF_Led() { //функция плавного выключения

  stateLed = false; //флаг состояния фонаря выкл.

  for (unsigned int i = 255; i >= 1; i--) {

    analogWrite(pwmLed, (i * i) / 255);

    delay(5);
  }
}

void ON_Led() { //функция плавного включения

  stateLed = true; //флаг состояния фонаря вкл.

  for (unsigned int i = 0; i <= 255; i++) {

    analogWrite(pwmLed, (i * i) / 255);

    delay(10);
  }
}

bool IR_dt() { //проверка на наличие препятствия перед оптопарой
  int ReadIR = analogRead_C(IR_D);
  PORTB |= (1 << 2); //устанавливаем на РВ2 высокий уровень, включаем ИК диод
  delay(1);
  ReadIR = ReadIR - analogRead_C(IR_D);
  PORTB &= ~(1 << 2); //устанавливаем на РВ2 низкий уровень, выключаем ИК диод
  return ReadIR > 300;
}

unsigned int analogRead_C(byte channel) {
  ADMUX = channel;
  ADCSRA |= 1 << ADEN;
  ADCSRA |= 1 << ADSC;
  while (!(ADCSRA & (1 << ADIF)));
  ADCSRA |= 1 << ADIF;
  byte low  = ADCL;
  byte high = ADCH;
  ADCSRA &= ~(1 << ADEN);
  return (high << 8) | low;
}

void loop() {

  if (!(PINB & (1 << PINB3))) { //проверка состояния двери
    if (!stateDoor) { //если была закрыта и ее открыли
      stateDoor = true; //меняем ее статус на открыто
      if (!stateLed) { //если фонарь выключен, включаем
        ON_Led();
      }
    }
  }
  else {//дверь закрыта
    delay(50);
    if (PINB & (1 << PINB3)) { //защита от помех
      if (stateDoor) { //если была открыта и ее закрыли
        stateDoor = false; //меняем статус на закрыто
        if (stateLed) { //если фонарь включен, выключаем
          OFF_Led();
          delay(2000);
        }
      }
    }
  }

  if (IR_dt()) { //проверка на наличие препятствия

    delay(100);
    boolean up = true; //флаг от повторного срабатывания

    while (true) {

      if (up) {
        if (stateLed) OFF_Led(); //если фонарь включен, выключаем
        else ON_Led(); //если фонарь выключен, включаем
        up = false;
      }

      if (!IR_dt()) { //при отсутствии препятствия выходим из цикла
        break;
      }
    }
    delay(200);
  }
}

По логике должно быть, если перед оптопарой есть припятствие программа входит в цикл while на 90 строке, выполняет действие один раз и остается в нем пока не убрать препятствие, а на деле получается что действие происходит циклично фонать постоянно загорается и гаснет. Флаг up в упор не хочет видеть.

Со вторым багом, пока писал ответ, сам разобрался)

А третий баг вообще за гранью моего понимания) Если у меня на PB3 высокий уровень (дверь закрыта) на PB2 пультоскопом переодически видны короткие импульсы, тоесть программа работае нормально, но как только я PB3 притягиваю к земле, на PB2 появляется сигнал похожий на шим, с частотой 680гц и скважность примерно 90%, датчик перестает работать до тех пор пока не уберу низкий уровень с PB3. Как то так.

bodriy2014
bodriy2014 аватар
Offline
Зарегистрирован: 12.05.2015

Alex_Mirko пишет:

#define pwmLed 0
#define IR_LED 2
#define DOORS 3
#define IR_D 2

boolean stateLed = false;
boolean stateDoor = false;

void setup() {
  analogWrite(pwmLed, 0);
  DDRB &= ~(1 << 3); //устанавливаем РВ3 на вход
  DDRB |= (1 << 2); //устанавливаем РВ2 на выход
  PORTB &= ~(1 << 2); //устанавливаем на РВ2 низкий уровень

}

void OFF_Led() { //функция плавного выключения

  stateLed = false; //флаг состояния фонаря выкл.

  for (unsigned int i = 255; i >= 1; i--) {

    analogWrite(pwmLed, (i * i) / 255);

    delay(5);
  }
}

void ON_Led() { //функция плавного включения

  stateLed = true; //флаг состояния фонаря вкл.

  for (unsigned int i = 0; i <= 255; i++) {

    analogWrite(pwmLed, (i * i) / 255);

    delay(10);
  }
}

bool IR_dt() { //проверка на наличие препятствия перед оптопарой
  int ReadIR = analogRead_C(IR_D);
  PORTB |= (1 << 2); //устанавливаем на РВ2 высокий уровень, включаем ИК диод
  delay(1);
  ReadIR = ReadIR - analogRead_C(IR_D);
  PORTB &= ~(1 << 2); //устанавливаем на РВ2 низкий уровень, выключаем ИК диод
  return ReadIR > 300;
}

unsigned int analogRead_C(byte channel) {
  ADMUX = channel;
  ADCSRA |= 1 << ADEN;
  ADCSRA |= 1 << ADSC;
  while (!(ADCSRA & (1 << ADIF)));
  ADCSRA |= 1 << ADIF;
  byte low  = ADCL;
  byte high = ADCH;
  ADCSRA &= ~(1 << ADEN);
  return (high << 8) | low;
}

void loop() {

  if (!(PINB & (1 << PINB3))) { //проверка состояния двери
    if (!stateDoor) { //если была закрыта и ее открыли
      stateDoor = true; //меняем ее статус на открыто
      if (!stateLed) { //если фонарь выключен, включаем
        ON_Led();
      }
    }
  }
  else {//дверь закрыта
    delay(50);
    if (PINB & (1 << PINB3)) { //защита от помех
      if (stateDoor) { //если была открыта и ее закрыли
        stateDoor = false; //меняем статус на закрыто
        if (stateLed) { //если фонарь включен, выключаем
          OFF_Led();
          delay(2000);
        }
      }
    }
  }

  if (IR_dt()) { //проверка на наличие препятствия

    delay(100);
    boolean up = true; //флаг от повторного срабатывания

    while (true) {

      if (up) {
        if (stateLed) OFF_Led(); //если фонарь включен, выключаем
        else ON_Led(); //если фонарь выключен, включаем
        up = false;
      }

      if (!IR_dt()) { //при отсутствии препятствия выходим из цикла
        break;
      }
    }
    delay(200);
  }
}

По логике должно быть, если перед оптопарой есть припятствие программа входит в цикл while на 90 строке, выполняет действие один раз и остается в нем пока не убрать препятствие, а на деле получается что действие происходит циклично фонать постоянно загорается и гаснет. Флаг up в упор не хочет видеть.

Со вторым багом, пока писал ответ, сам разобрался)

А третий баг вообще за гранью моего понимания) Если у меня на PB3 высокий уровень (дверь закрыта) на PB2 пультоскопом переодически видны короткие импульсы, тоесть программа работае нормально, но как только я PB3 притягиваю к земле, на PB2 появляется сигнал похожий на шим, с частотой 680гц и скважность примерно 90%, датчик перестает работать до тех пор пока не уберу низкий уровень с PB3. Как то так.

Сделайте up глобальной переменной увидит сразу. Нужно обьявить в начале.

boolean stateLed = false;
boolean stateDoor = false;
boolean up = true; //флаг от повторного срабатывания

После отпишитесь другие баги остались или нет.

 

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

Alex_Mirko, по скетчу видно что вы набрали кусков из интернета, и не до конца понимаете как всё это работает. Но есть вообщё пёрлы, например это:

for (unsigned int i = 255; i >= 1; i--) {
 analogWrite(pwmLed, (i * i) / 255);
delay(5);
}

Это ж  жуть какой изврат. Зачем вы перемножаете переменную счёта? Вот так разве сделать нельзя?

for (int i=255; i>=0; i-- ) {
    analogWrite(pwmLed, i);

Аналогичный трэш -вычитание двух значений аналогрида в 45 строке, повторное ветвление условий 64/74 строка. Проблема с PB2 сходу не видна, но скорее всего что-то ещё и с флагами нумудрили, что после всего вышесказанного будет не удивительно.

Alex_Mirko
Alex_Mirko аватар
Offline
Зарегистрирован: 16.05.2016

bodriy2014, спасибо, буду дома попробую

dimax, код брал из головы, и в общем представляю как он работает, ошибки от нехватки опыта.
Что касается цикла for значения счетчика умножается для получения параболы, так как отношение значения ШИМ и яркость свечения светодиода не линейно.

Что касается аналогрида, я получаю первое значение когда ик светодиод выключен, второе когда он включен, вычисляю их разницу и определяю есть препятствие или нет.

В 64 строке я делаю проверку на низкий уровень, в 74 через delay на высокий. Просто защита от ложного срабатывания, ее сначала небыло.

bodriy2014
bodriy2014 аватар
Offline
Зарегистрирован: 12.05.2015

Alex_Mirko пишет:
.....Что касается цикла for значения счетчика умножается для получения параболы, так как отношение значения ШИМ и яркость свечения светодиода не линейно. ....

Неожиданный поворот!

Я тоже подумал что код у вас напихан многим ненужным, но писать не стал.

Вот за что я люблю форум пришел человек за советом, а между делом подсказал мне как просто убрать эту нелинейность в свечении кристалла.!))

На счет АЦП если тини13 работает на частоте 9,6МГц попробуйте сменить фьюзы на 1,2МГц. Не знаю с чем связанно но наблюдал значительное дребезжание показаний на 9,6 пробовал разные режимы, ушло только на 1,2/

 

Alex_Mirko
Alex_Mirko аватар
Offline
Зарегистрирован: 16.05.2016

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

Что касается нелинейности, с нее все и началось) хотел именно плавное включение, что бы глаза успевали привыкнуть, делал много разных опытов, но остановился именно на этой формуле)

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

Alex_Mirko, и что, заметно на глаз разница в управлению яркостью?  Имхо нужен чёткий логарифм, что б глаз ощутил "линейность" регулировки.  По хорошему нужно делать лог. формулу рассчёта и под неё 16-битный, или специальный софт-шим, правда никто ещё не заморачивался настолько глубоко :))

Alex_Mirko
Alex_Mirko аватар
Offline
Зарегистрирован: 16.05.2016

dimax, Разница есть, конечно, полной линейности так не получить) но учитывая простату формулы мне этого хватает)

Alex_Mirko
Alex_Mirko аватар
Offline
Зарегистрирован: 16.05.2016
#define pwmLed 0
#define IR_LED 2
#define DOORS 3
#define IR_D 2

boolean stateLed = false;
boolean stateDoor = false;
boolean up = true; //флаг от повторного срабатывания

void setup() {
  analogWrite(pwmLed, 0);
  DDRB &= ~(1 << 3); //устанавливаем РВ3 на вход
  DDRB |= (1 << 2); //устанавливаем РВ2 на выход
  PORTB &= ~(1 << 2); //устанавливаем на РВ2 низкий уровень

}

void OFF_Led() { //функция плавного выключения

  stateLed = false; //флаг состояния фонаря выкл.

  for (unsigned int i = 255; i >= 1; i--) {

    analogWrite(pwmLed, (i * i) / 255);

    delay(5);
  }
}

void ON_Led() { //функция плавного включения

  stateLed = true; //флаг состояния фонаря вкл.

  for (unsigned int i = 0; i <= 255; i++) {

    analogWrite(pwmLed, (i * i) / 255);

    delay(10);
  }
}

unsigned int analogRead_C(byte channel) {
  ADMUX = channel;
  ADCSRA |= 1 << ADEN;
  ADCSRA |= 1 << ADSC;
  while (!(ADCSRA & (1 << ADIF)));
  ADCSRA |= 1 << ADIF;
  byte low  = ADCL;
  byte high = ADCH;
  ADCSRA &= ~(1 << ADEN);
  return (high << 8) | low;
}

boolean IR_dt() { //проверка на наличие припятствия перед оптопарой
  delay(100);
  int ReadIR = analogRead_C(IR_D);
  PORTB |= (1 << 2); //устанавливаем на РВ2 высокий уровень, включаем ИК диод
  delay(1);
  ReadIR = ReadIR - analogRead_C(IR_D);
  PORTB &= ~(1 << 2); //устанавливаем на РВ2 низкий уровень, выключаем ИК диод
  
  return ReadIR > 300;
}

void loop() {

  if (!(PINB & (1 << PINB3))) { //проверка состояния двери
    if (!stateDoor) { //если была закрыта и ее открыли
      stateDoor = true; //меняем ее статус на открыто
      if (!stateLed) { //если фонарь выключен, включаем
        ON_Led();
      }
    }
  }
  else {//дверь закрыта
    delay(50);
    if (PINB & (1 << PINB3)) { //защита от помех
      if (stateDoor) { //если была открыта и ее закрыли
        stateDoor = false; //меняем статус на закрыто
        if (stateLed) { //если фонарь включен, выключаем
          OFF_Led();
        }
        delay(2000);
      }
    }
  }

  if (IR_dt()) { //проверка на наличие препятствия
    
    up = true; 
    
    while (true) {

      if (up) {
        if (stateLed) OFF_Led(); //если фонарь включен, выключаем
        else ON_Led(); //если фонарь выключен, включаем
        up = false;
      }
      if (!IR_dt()){
        break;
      }
    }
    delay(200);
  }
}

Заработало) снижение скорости и перенос переменной результата не дал, причина была в частых обращениях к АЦП, добавил delay(100) в функцию IR_dt() и все нормально заработало. 

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

Alex_Mirko пишет:

dimax, Разница есть, конечно, полной линейности так не получить) но учитывая простату формулы мне этого хватает)

Когда нужно просто плавно зажечь/погасить, и при этом никаких паралельных процессов нет можно использовать другой способ, я придумал его когда PWM был занят :) Преимущество в более высоком разрешении софт-шима, и соответссно в большей плавности.  "Линейность" регулировки рассчитывается возведением во вторую степень инкременирующегося счётчика. 8-битный PWM так плавно  регулировать не может. В данном примере 11 битный софт-PWM и плавное зажигание.

void setup(){
 pinMode(12,OUTPUT);
  uint16_t shag=0, logout=0;
   while(1){
    PORTB|=1<<PB4;
     if (logout>=1992) {break;}
      delayMicroseconds(logout);
     PORTB&=~(1<<PB4);
    delayMicroseconds(2000-logout);
   logout= pow(shag,2)/2000; 
  shag+=2;
 }

}


void loop() {}  

 

ggarry
Offline
Зарегистрирован: 21.01.2016

Alex_Mirko пишет:

dimax, Разница есть, конечно, полной линейности так не получить) но учитывая простату формулы мне этого хватает)

Большой респектище за чудный способ линеаризации свечения диодов, уже использовал в заброшенном проекте. Но простАта  формулы сразила наповал.

Alex_Mirko
Alex_Mirko аватар
Offline
Зарегистрирован: 16.05.2016

dimax, Спасибо, надо будет по эксперементировать) на выходе получается таже самая парабола только с расширеной разрядностью, и шим не надо задействовать, для моргалок самое то)

ggarry, простАта наше все =D

taxi242
Offline
Зарегистрирован: 28.03.2017

Добрый день.

Прошу строго не пинать и ругать так как в программировании полный 0. Хотел бы собрать схему управления вентиляторами еще с этого поста http://arduino.ru/forum/programmirovanie/attiny13a-101-primenenie?page=3#comment-47411 Нужно похожее в виду ее миниатюрности и наличии двух зон регулировки.

Столкнулся с проблемой при вытягивании готовой прошивки для Тиньки, используя Arduino IDE 1.6.7 а именно:

Скетч использует 1 130 байт (110%) памяти устройства. Всего доступно 1 024 байт.
Глобальные переменные используют 8 байт динамической памяти.
processing.app.debug.RunnerException: Скетч слишком большой; прочитайте http://www.arduino.cc/en/Guide/Troubleshooting#size
at cc.arduino.Compiler.size(Compiler.java:315)
at cc.arduino.Compiler.build(Compiler.java:156)
at processing.app.Sketch.build(Sketch.java:1108)
at processing.app.Sketch.build(Sketch.java:1083)
at processing.app.Editor$BuildHandler.run(Editor.java:2011)
at java.lang.Thread.run(Thread.java:745)
Скетч слишком большой; прочитайте http://www.arduino.cc/en/Guide/Troubleshooting#size
 
Можете подсказать что тут не так с кодом или может виновато ПО?

 

 

 

bodriy2014
bodriy2014 аватар
Offline
Зарегистрирован: 12.05.2015

taxi242 пишет:

Добрый день.

Прошу строго не пинать и ругать так как в программировании полный 0. Хотел бы собрать схему управления вентиляторами еще с этого поста http://arduino.ru/forum/programmirovanie/attiny13a-101-primenenie?page=3#comment-47411 Нужно похожее в виду ее миниатюрности и наличии двух зон регулировки.

Столкнулся с проблемой при вытягивании готовой прошивки для Тиньки, используя Arduino IDE 1.6.7 а именно:

Скетч использует 1 130 байт (110%) памяти устройства. Всего доступно 1 024 байт.
Глобальные переменные используют 8 байт динамической памяти.
processing.app.debug.RunnerException: Скетч слишком большой; прочитайте http://www.arduino.cc/en/Guide/Troubleshooting#size
at cc.arduino.Compiler.size(Compiler.java:315)
at cc.arduino.Compiler.build(Compiler.java:156)
at processing.app.Sketch.build(Sketch.java:1108)
at processing.app.Sketch.build(Sketch.java:1083)
at processing.app.Editor$BuildHandler.run(Editor.java:2011)
at java.lang.Thread.run(Thread.java:745)
Скетч слишком большой; прочитайте http://www.arduino.cc/en/Guide/Troubleshooting#size
 
Можете подсказать что тут не так с кодом или может виновато ПО?

Вы этот код хотите в тини13 влить?


void setup()
{ 
  PORTB=0x00;  //записать в весь порт В 0
  DDRB=0x01;   //настроить порт В 0x01: по другому 000001 (1 означает выход, 0 вход)
  
//Настройка аппаратного ШИМ 
  TCCR0A=0x83;  //настраиваем аппартанный шим на PB0 с частотой 37,5кГц(аппаратный шим только на PB0 и PB1)
  TCCR0B=0x83;  //на PB1 (второй шим) ничего делать не надо
  OCR0A=0x00;
  
} 
void loop()
{
  {
    int valo = analogRead(A3);        //Читаем термистор
   valo = map(valo,400,750,40,255);   // масштабируем аналог в шим
   analogWrite(1,valo);               //выводим шим на вентелятор
   valo = analogRead(A3);             // это выражение может показаться лишним, но без него программа не работает.
   if(valo<=400)analogWrite(1,0);     //если температура ниже чем 30гр. то шим ноль
   if(valo>=750)analogWrite(1,255);   //если выше 65 то шим на максимум
  }
  {
 
   int val = analogRead(A1);        //то же самое, только для второго вентелятора.
   val = map(val,400,750,40,255);
   analogWrite(0,val); 
   val = analogRead(A1);
   if(val<=400)analogWrite(0,0);
   if(val>=750)analogWrite(0,255);
  }
  
}

 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Кота покажи.

taxi242
Offline
Зарегистрирован: 28.03.2017

Та как бы да, Илья73 реализовал это в железе. Или не получиться?

bodriy2014
bodriy2014 аватар
Offline
Зарегистрирован: 12.05.2015

taxi242 пишет:

Та как бы да, Илья73 реализовал это в железе. Или не получиться?

Проверил в симуляторе и в железе работает.

Схему и код прилагаю.

#define Min_C 100 // значение  при котором отключаем вентилятор
#define Max_C 180 // значение  при котором  вентилятор на максимум

byte dvig_1, dvig_2;
void setup() {
  DDRB |= (1 << 0) | (1 << 1);//пины на выход
  TCCR0A = 0b10100011; //режим fast pwm
  TCCR0B = 0b00000001; //выбираем скорость ШИМ делителем
}

void loop() {
  //первый двигатиель
  dvig_1 = analogRead_C(3) / 4; // РВ3 в ATtiny13
  if (dvig_1 <= Min_C) {
    OCR0A = 0;
  } else if (dvig_1 >= Max_C) {
    OCR0A = 255;
  } else {
    OCR0A = dvig_1;
  }
  //второй двигатиель
  dvig_2 = analogRead_C(2) / 4; // РВ4 в ATtiny13
  if (dvig_2 <= Min_C) {
    OCR0B = 0;
  }  else if (dvig_2 >= Max_C) {
    OCR0B = 255;
  } else {
    OCR0B = dvig_2;
  }
}

unsigned int analogRead_C(byte channel) {//функция измерения АЦП
  ADMUX = channel; // ADC pin
  ADCSRA |= 1 << ADEN;
  ADCSRA |= 1 << ADSC;
  while (!(ADCSRA & (1 << ADIF)));
  ADCSRA |= 1 << ADIF;
  byte low  = ADCL;
  byte high = ADCH;
  return (high << 8) | low;
}

 

ardu2414
ardu2414 аватар
Offline
Зарегистрирован: 25.12.2015

Привет всем. Вопрос такой выйдет ли из ATTINY13A контроллер для (L293D) драйвера или "H bridge" мостов.

ardu2414
ardu2414 аватар
Offline
Зарегистрирован: 25.12.2015

ardu2414
ardu2414 аватар
Offline
Зарегистрирован: 25.12.2015

Вот схема и вот принцип работы программы:
 4 выхода от ATTINY13A (PB4, PB3, PB1, PB0) управляет ключами драйвера. А "BP2 вход которому потключение потенциометр" это главный управления.  Суть PB2 является (от 0 до 50 градации потенциометра ) в программа ничего не выполняется а при увеличение с 51 до 509 начнёт передавать импульс по выходам с права налево при этом увеличивается скорость передачи импульс. А когда PB2= с 510 до 559 градаций "стоп", а когда PB2= с 560 до 1000 градаций импулсы будут поступать к выходам с лева на права. Когда PB2= с 1001 до 1023 это "стоп".
     1-? Влезет ли токой программа в 1KB именно в "ATTINY13A"?
     2-? Почтий эту программу я написал в Arduino IDE. Но в CodeVisionAVR е могу толка обращаться к пинам "а сделать Analog Reference в CodeVisionAVR немогу перерыл почти всю INTERNET или я туплю или немогу попасть туда куда надо.
   3-? Кто какую редактор предлагает. Я готов перейти и начать если поможете разобраться (Atmel Studio, Algarithm Builder, BASCOM-AVR)

   Прошу извинить за не грамотность, ошибок в надписей язык Русский это второй мой язык!
   И прошу не пинайте по голову новичка, прошу помочь разобраться с  CodeVisionAVR е с "Analog Reference" ым как это делается... Спасибо всем

ardu2414
ardu2414 аватар
Offline
Зарегистрирован: 25.12.2015

И вот программа который работает на ATmega8:
int SMP[]={3,5,6,9};
int SeS=0; //Sensor of Speed
void setup(){
int index;
for(index=0; index<=3; index++){
pinMode(SMP[index],OUTPUT);
pinMode(SeS, INPUT);
}
}
void loop(){
int SSU=analogRead(A0); //Speed sensorni uqish
int SeS=map(SSU, 0, 1023, 2, 265);
int index;
int PTS=SeS;
for(index=0; index<=3; index++){
digitalWrite(SMP[index], HIGH),
digitalWrite(SMP[index],LOW),
delay(PTS);
}

}

Это программа очень простая но не тот который я писал наверху для ATTINY13A .

bodriy2014
bodriy2014 аватар
Offline
Зарегистрирован: 12.05.2015

ardu2414 пишет:
Вот схема и вот принцип работы программы:  4 выхода от ATTINY13A (PB4, PB3, PB1, PB0) управляет ключами драйвера. А "BP2 вход которому потключение потенциометр" это главный управления.  Суть PB2 является (от 0 до 50 градации потенциометра ) в программа ничего не выполняется а при увеличение с 51 до 509 начнёт передавать импульс по выходам с права налево при этом увеличивается скорость передачи импульс. А когда PB2= с 510 до 559 градаций "стоп", а когда PB2= с 560 до 1000 градаций импулсы будут поступать к выходам с лева на права. Когда PB2= с 1001 до 1023 это "стоп".      1-? Влезет ли токой программа в 1KB именно в "ATTINY13A"?      2-? Почтий эту программу я написал в Arduino IDE. Но в CodeVisionAVR е могу толка обращаться к пинам "а сделать Analog Reference в CodeVisionAVR немогу перерыл почти всю INTERNET или я туплю или немогу попасть туда куда надо.    3-? Кто какую редактор предлагает. Я готов перейти и начать если поможете разобраться (Atmel Studio, Algarithm Builder, BASCOM-AVR)    Прошу извинить за не грамотность, ошибок в надписей язык Русский это второй мой язык!    И прошу не пинайте по голову новичка, прошу помочь разобраться с  CodeVisionAVR е с "Analog Reference" ым как это делается... Спасибо всем

Привет.

Писал код в котором тини13 управляет шаговым движком, потециометрм задавалась скорость движения и направление, до середины оно понижало скорость в одну сторону с середины потенциометра оно меняло направление и повышало в другую.

Был задействовано 1 аналоговый вход и 4 цифровых.

 

ardu2414
ardu2414 аватар
Offline
Зарегистрирован: 25.12.2015

Почтий всю про "ATtiny13A 101 применение" пролистал только вначале был кой что про вольтметр и всё про analogRead почти забыли. Прошу всех кто сможет обесните новичку как считать с аналоговых входов, выходов состоянии и сравнить, или делать что-то крутое! Пожалуйста

bodriy2014
bodriy2014 аватар
Offline
Зарегистрирован: 12.05.2015

ardu2414 пишет:
Почтий всю про "ATtiny13A 101 применение" пролистал только вначале был кой что про вольтметр и всё про analogRead почти забыли. Прошу всех кто сможет обесните новичку как считать с аналоговых входов, выходов состоянии и сравнить, или делать что-то крутое! Пожалуйста

На первой страничке же есть.

Если вас не устраивает analogRead , там выложили готовую функцию

int Volts = 0; // Вольтметр
void setup()
{
}
void loop()
{
 Volts = analogRead_C(2); // РВ4 в ATtiny13
}

unsigned int analogRead_C(byte channel){  
  ADMUX = channel; // ADC pin
  ADCSRA |= 1<<ADEN;
  ADCSRA |= 1<<ADSC;
  while(!(ADCSRA & (1<<ADIF)));
  ADCSRA |= 1<<ADIF;
  byte low  = ADCL;
  byte high = ADCH;
  ADCSRA &= ~(1 << ADEN);  // отключаем АЦП, для уменьшения энергопотребления
  return (high << 8) | low;
}

 

vovka1021
Offline
Зарегистрирован: 02.02.2016

12-led-vu-meter кто нить реализовал для тиньки8? можете дать схему подключения и код. спасибо.

ranzer
Offline
Зарегистрирован: 19.04.2017

Здравствуйте. Подскажите пожалуйста, возможно ли запрограммировать Attiny13 через Arduino uno на выполнение fade поочередно на три разных светодиода?

bodriy2014
bodriy2014 аватар
Offline
Зарегистрирован: 12.05.2015

ranzer пишет:

Здравствуйте. Подскажите пожалуйста, возможно ли запрограммировать Attiny13 через Arduino uno на выполнение fade поочередно на три разных светодиода?

На тини13 всего две ножки имеют ШИМ, но программно можно сделать на три ноги.

ranzer
Offline
Зарегистрирован: 19.04.2017

Вот, программно, это как? Без Arduino, напрямую?