Нужна помощь с HC-SR04 и Attiny13

denyang
Offline
Зарегистрирован: 05.08.2013
#define T 1
#define E 0
#define led 2

void setup() 
{
pinMode(T, OUTPUT);
pinMode(E, INPUT);
digitalWrite(E, HIGH);
pinMode(led, OUTPUT);

}

void loop() 
{
if (Ultrasonic(T, E) < 40);
&nbsp;{
&nbsp;digitalWrite(led, HIGH);
&nbsp;delay (100000);
&nbsp;}
delay(50);
}

int Ultrasonic(byte Trig_pin, byte Echo_pin)
{
&nbsp;digitalWrite(Trig_pin, HIGH);
&nbsp;delayMicroseconds(10);
&nbsp;digitalWrite(Trig_pin, LOW); 
&nbsp;return pulseIn(Echo_pin, HIGH, 20000)/29.0/2;
}

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

 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013
Размер скетча в двоичном коде: 1 184 байт (из 1 024 байт максимум)
пока не получилось(
jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013
#define T 1
#define E 0
#define led 2

void setup() {
  DDRB = 1<<T;
  DDRB = 0<<E;
  DDRB = 1<<led;
  PORTB = 1<<E;

}

void loop() {
  if (Ultrasonic() < 40){
    PORTB = 1<<led;
    //delay (100000); //зачем такая большая задержка 100сек
  }
  else{
    PORTB = 0<<led;
    //delay (100000); //зачем такая большая задержка 100сек
  }
  delay(50);
}

int Ultrasonic(){
  PORTB = 1<<T;
  delayMicroseconds(10);
  PORTB = 0<<T;
  unsigned long st = micros();
  while((PINB & 1) == HIGH){
    if(micros() - st > 20000){
      return (micros()-st)/58.0; //хз правильна ли эта строка, тероретически нужно возвращать 0
    }
    return (micros()-st)/58.0;
  }
}
Размер скетча в двоичном коде: 1 020 байт (из 1 024 байт максимум)
но хз правильно ли все работает))
если delay раскоментировать уже не влезает
 
один момент. когда делите на число с запятой теоретически и планируете получить число с запятой, но тип возвращаемой переменной int отсекает все после запятой, то есть смысла в этом нет получается, хотя может я ошибаюсь
если я не ошибаюсь то все гораздо лучше
#define T 1
#define E 0
#define led 2

void setup() {
  DDRB = 1<<T;
  DDRB = 0<<E;
  DDRB = 1<<led;
  PORTB = 1<<E;

}

void loop() {
  if (Ultrasonic() < 40){
    PORTB = 1<<led;
    //delay (100000); //зачем такая большая задержка 100сек
  }
  else{
    PORTB = 0<<led;
    //delay (100000); //зачем такая большая задержка 100сек
  }
  delay(50);
}

int Ultrasonic(){
  PORTB = 1<<T;
  delayMicroseconds(10);
  PORTB = 0<<T;
  unsigned long st = micros();
  while((PINB & 1) == HIGH){
    if(micros() - st > 20000){
      return (micros()-st)/58;
    }
    return (micros()-st)/58;
  }
}

 

Размер скетча в двоичном коде: 492 байт (из 1 024 байт максимум)
 
но тогда и ваш код влезает
#define T 1
#define E 0
#define led 2

void setup() 
{
pinMode(T, OUTPUT);
pinMode(E, INPUT);
digitalWrite(E, HIGH);
pinMode(led, OUTPUT);

}

void loop() 
{
if (Ultrasonic(T, E) < 40);
{
digitalWrite(led, HIGH);
delay (100000);
}
delay(50);
}

int Ultrasonic(byte Trig_pin, byte Echo_pin)
{
digitalWrite(Trig_pin, HIGH);
delayMicroseconds(10);
digitalWrite(Trig_pin, LOW); 
return pulseIn(Echo_pin, HIGH, 20000)/58;
}

 

Размер скетча в двоичном коде: 814 байт (из 1 024 байт максимум)
хотя в вашем коде ошибка. получается светодиод будет гореть всегда, нужно еще else добавить чтобы его потушить

 

art100
Offline
Зарегистрирован: 09.03.2014

У меня на столе  платка готовая прикручена.

А с такой платкой есть шансы? или у вас библиотеки не стандартные?

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

а она здесь при чем? разговор про тиньку шел а не рациональность

хотя в данном конкретном случае и тиньки достаточно если ничего больше не будет делать или совсем мало чего

denyang
Offline
Зарегистрирован: 05.08.2013

а точно ли "return pulseIn(Echo_pin, HIGH, 20000)/58;" равнозначно "return pulseIn(Echo_pin, HIGH, 20000)/29.0/2;"? У меня именно из-за 29.0 резко увеличивался размер скетча

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

да хз. вы так написали что фиг разберешь, скобок нет. поэтому сначала делить на 29 потом на 2. получаем 58

denyang
Offline
Зарегистрирован: 05.08.2013

так это не я писал :) это maksim в теме "Автоматическая подсветка лестницы и ММ5450"

ссылка http://www.arduino.ru/forum/programmirovanie/avtomaticheskaya-podsvetka-lestnitsy-i-mm5450

пост №4

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

так там памяти было достаточно

denyang
Offline
Зарегистрирован: 05.08.2013

это то понятно что памяти достаточно... меня эта точка в чмсле 29 очень смущает... и самое обидное что не пойму её роль

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

скорее всего чтобы получить максимальную точность, в смысле количество знаков. 25,5 точнее чем 26 например

я так предполагаю

denyang
Offline
Зарегистрирован: 05.08.2013

Ясно. С точностью более менее понятно. Новая проблема, написал программку которая по нажатию кнопки пишет значение расстояния в память. Но в памитя почему то одни нули пишутся. Подскажите что не так сделал?

 

#include <EEPROM.h>

//Устанавливаем контакты для датчика
#define  T  0
#define  E  1
#define led  2
int flag=0; 
int i=0;

void setup() 
{
  pinMode(led, OUTPUT);
  pinMode(T, OUTPUT);
  pinMode(E, INPUT);
  digitalWrite(E, HIGH);
}

void loop() 
{
  int D = Ultrasonic(T, E);
  if(digitalRead(4)==HIGH&&flag==0) 
     { 
       digitalWrite(led, HIGH);
       EEPROM.write(i, D);
       flag=1; 
       i=i+1;
       delay (100);
       if (i > 64) i=0;      
     } 
     
     if(digitalRead(4)==LOW&&flag==1)//если кнопка НЕ нажата 
     { 
       flag=0;//обнуляем переменную flag 
       digitalWrite(led, LOW);
     }
  delay(50);
}

int Ultrasonic(int Trig_pin, int Echo_pin)
{
  digitalWrite(Trig_pin, HIGH);
  delayMicroseconds(10);
  digitalWrite(Trig_pin, LOW);   
  return pulseIn(Echo_pin, HIGH,20000)/58;
}

 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

а вы проверяли в ядре для тиньки прописана работа с еепром? есть ли поддержка

хотя сам и отвечу вот что поддерживает ядро

map()
random()
randomSeed()
millis()
micros() 
delay()
delayMicroseconds() *
analogRead()
analogWrite() 
pinMode()
digitalRead() 
digitalWrite()
pulseIn() (Untested)
shiftIn() (Untested)
shiftOut() (Untested)

 

denyang
Offline
Зарегистрирован: 05.08.2013

конечно проверил. после загрузки скетча в памяти одни FF после нажатия кнопок появляются нули

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

интересно. в описании к ядру эта функция не прописана

denyang
Offline
Зарегистрирован: 05.08.2013

но ведь содержимое памяти меняется :)

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

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

http://forum.arduino.cc/index.php?PHPSESSID=78gh79m79tmomqi38v4fug4r72&t...

кстати где нашел в ядре запись о еепром?

denyang
Offline
Зарегистрирован: 05.08.2013

Изначально то я писал скетч на зажигание светодиода при определенном расстоянии и меня смутило что светодиод ну нивкакую не хотел зажигаться. Дай думаю посмотрю а какие значения выдает датчик, а он оказывается вон что творит. А есть ли способ передать данные в копм через USBISP программатор?

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

через программатор нет

denyang
Offline
Зарегистрирован: 05.08.2013

https://arduino.ru/forum/programmirovanie/attiny13a-101-primenenie (пост 1) тут написано в виде примера использование eeprom 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

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

MaksMS
Offline
Зарегистрирован: 11.03.2013

jeka_tm пишет:

через программатор нет

Как это нет ??

-U eeprom:w:eeprom.hex

 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

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

denyang
Offline
Зарегистрирован: 05.08.2013

Блин... ну все перепробовал... на Atmege8 скетч прекрасно работает, сохраняет в память показания расстояния, на тиньке только нули :( Люди добрые, кто работал с данными датчиками на тиньке, подскажите что я деляю не так?

denyang
Offline
Зарегистрирован: 05.08.2013

что то мне подсказывает, проблема в этой строчке

return pulseIn(Echo_pin, HIGH,20000)/58;

как то тинька некооректно ее отрабатывает

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

а мега корректно?

denyang
Offline
Зарегистрирован: 05.08.2013

мега корректно

 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

значит в коде дело

смотрите на какой частоте работает тинька и что прописано в боардс

denyang
Offline
Зарегистрирован: 05.08.2013

тинька работает на частоте 1 Мгц, а вот как это связать с кодом пока не знаю...

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

в board.txt что написано? какая частота?

мега на какой частоте работает?

 

denyang
Offline
Зарегистрирован: 05.08.2013

у тиньки 

attiny13def.name=Attiny13 1.2 MHz (default)
attiny13def.upload.using=arduino:arduinoisp
attiny13def.upload.maximum_size=1024
attiny13def.bootloader.low_fuses=0x6A
attiny13def.bootloader.high_fuses=0xFF
attiny13def.build.mcu=attiny13
attiny13def.build.f_cpu=1200000L
attiny13def.build.core=core13
 
у меги8
atmega8.upload.protocol=arduino
atmega8.upload.maximum_size=7168
atmega8.upload.speed=19200
atmega8.bootloader.low_fuses=0xdf
atmega8.bootloader.high_fuses=0xca
atmega8.bootloader.path=atmega8
atmega8.bootloader.file=ATmegaBOOT-prod-firmware-2009-11-07.hex
atmega8.bootloader.unlock_bits=0x3F
atmega8.bootloader.lock_bits=0x0F
atmega8.build.mcu=atmega8
atmega8.build.f_cpu=16000000L
atmega8.build.core=arduino
 

 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

попробуйте тиньку без делителя запустить

фьюзы 7A FF

и изменить эту строку

attiny13def.build.f_cpu=9600000L

denyang
Offline
Зарегистрирован: 05.08.2013

я просто выбрал в списке частоту тиньки 9,6 Мгц

не помогло

denyang
Offline
Зарегистрирован: 05.08.2013

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

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

тогда наверно тупо не хвататет оперативки. меняйте типы данных на минимально возможные при которых будет работать int--byte--boolean

digitalwrite меняйте на прямое управление портом

 

denyang
Offline
Зарегистрирован: 05.08.2013

переменные поменял на byte. в скетче оставил только необходимое. размер 750 байт из 1024. реакции нету (

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

там всего 64 байта оперативки

а у вас флаг стоит int

управляйте портами напрямую

denyang
Offline
Зарегистрирован: 05.08.2013

вот что получилось, но все равно не работает. Может где ошибку сделал?

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

//Устанавливаем контакты для датчика
#define  T  0
#define  E  1
#define led  2
byte flag=0; 
byte i=0;

int main( void ) 
{
  DDRB |= (1<<0);
  DDRB |= (1<<2);
  DDRB &= ~(1<<1);  
  PORTB |= (1<<1);  

  while(1)
  {
   byte D = Ultrasonic(T, E);
    if ((PINB & (1<<PINB4))&&flag==0) 
    { 
       EEPROM_write(1, D);
       flag=1; 
       i=i+1;
       _delay_ms(100);
     } 
     
     if(!(PINB & (1<<PINB4))&&flag==1)//если кнопка НЕ нажата 
     { 
       flag=0;//обнуляем переменную flag 
     }
    _delay_ms(50);
    }
  return 0;
}

int Ultrasonic (byte TrigPin, byte EchoPin)
{ 
   PORTB |= (1<<TrigPin);
   delayMicroseconds(10);
   PORTB &= ~(1<<TrigPin);
  return pulseIn(EchoPin, HIGH,20000)/58;
}

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;
}

 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

уберите про еепром пока и проверяйте

и посмотрите что делает pulsein

unsigned long pulseIn(unsigned char pin, unsigned char stat, unsigned long timeout = 0xFFFFFFFF){
	unsigned long st;
	while(digitalRead(pin) != stat){if(micros() - st > timeout){return 0;}}
	st = micros();
	while(digitalRead(pin) == stat){if(micros() - st > timeout){return micros()-st;}}
	return micros()-st;
}

а вообще оно того стоит? цена тиньки около 17 рублей за шт, меги 8 около 25. стоит ли так извращаться?

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

http://ru.aliexpress.com/item/Free-Shipping-10PCS-TINY13A-ATTINY13A-ATTINY13A-SSU-SOP8-IC/878218636.html

http://ru.aliexpress.com/item/ATMEGA8A-AU-IC-Atmel-MCU-TQFP44-AVR-New-Original-100-Long-term-Supply/835672918.html

к тому же можно нормально программировать uart и через терминал узнать что делается в программе

памяти пинов больше, а размер совсем немного больше

denyang
Offline
Зарегистрирован: 05.08.2013

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

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

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

а когда памяти нехватает или пинов

для мелких задач пойдет

denyang
Offline
Зарегистрирован: 05.08.2013

единственно плохо, мегу ждать надо когда придет ( в розницу за 100 и выше руб. неохоа покупать) а тинька уже есть в наличии.... 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

еепром убери и может хватит

denyang
Offline
Зарегистрирован: 05.08.2013

еепром убрал, все равно глухо.

Попробовал написать аналогичную программку на Bascomе, данные с датчика пошли но искаженные, пытаюсь выситать коэффициент на который нужно умножать длительность импульса с датчика что бы получить нужные см.

dev_n
Offline
Зарегистрирован: 09.09.2014
//без pulseIn
int Ultrasonic(byte TrigPin, byte EchoPin){
  PORTB |= (1<<TrigPin);
  delayMicroseconds(10);
  PORTB &= ~(1<<TrigPin); 
  uint32_t micros_old_Ult = micros();
  while(!(PINB&(1<<EchoPin)) && micros()-micros_old_Ult < 500);
  micros_old_Ult = micros();
  while((PINB&(1<<EchoPin)) && micros()-micros_old_Ult < 20000);
  return (micros() - micros_old_Ult)/58; 
}

 

denyang
Offline
Зарегистрирован: 05.08.2013

Спасибо огромное! Помогло :)