загвоздка: обратный тамер с режимом ускоренного счёта

red.kaktus.37
red.kaktus.37 аватар
Offline
Зарегистрирован: 06.07.2015

День добрый, вечер, ночь, нужное подчеркнуть :)

Решился таки заюзать ардуинку и влип по полной. На сях с прямым доступом к таймерам реализовать могу, но так как это ардуина - не могу )

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

лишнего кода море, знаю и не оптимально, но для прошивки занимающей от силы 3 кило на 32х не критично :)

Если быть точным, то интересует, как используя millis() можно вести 2 отсчёта с разной скоростью но начинать отсчёт с того места, на котором был остановлен предидущий.

Сейчас имею следущее: переключаю режим с (millis()/1000) на (millis()/100) скорость увеличил время побежало, но при возвращении в штатный режим, время продолжает тикать с того места где переключился (старая версия)

и как сейчас выходит - после активации режима ускорения, после переключения в штатный, ускорение таки тикает... и досчитав до нуля взрывает бедных созданий потоками пара из парогенератора :( хотя на дисплее всё путём и до нуля там ещё почти час...

подскажите пожалуйста, где не прав :)

[code]
int digit1 = 11; //PWM Display pin 1
int digit2 = 10; //PWM Display pin 2
int digit3 = 9; //PWM Display pin 6
int digit4 = 6; //PWM Display pin 8

int segA = 3; //Display pin 14
int segB = 2; //Display pin 16
int segC = 7; //Display pin 13
int segD = 8; //Display pin 3
int segE = 12; //Display pin 5
int segF = 4; //Display pin 11
int segG = 5; //Display pin 15

int LedPin = 13;

int A = 14; //вход цепи на замыкание
int B = 15; //вход цепи на размыкание
int C = 16; //если 0 то ускоряем таймер
int D = 17; //если 0 то ускоряем таймер
int INPUTS;

int Coil_1 = 18;//выход бомба обезврежена
int Coil_2 = 19;//выход бомба 3.14_зданула

int setup_num = 3600;
int start_num;
int num_min;
int num_sec;
int num_time;

long interval = 500;
int ledState = LOW;
long previousMillis = 0;

int In_A;
int In_B;
int In_C;
int In_D;

unsigned long time;

void setup() {
  Serial.begin(9600);

  pinMode(segA, OUTPUT);
  pinMode(segB, OUTPUT);
  pinMode(segC, OUTPUT);
  pinMode(segD, OUTPUT);
  pinMode(segE, OUTPUT);
  pinMode(segF, OUTPUT);
  pinMode(segG, OUTPUT);

  pinMode(digit1, OUTPUT);
  pinMode(digit2, OUTPUT);
  pinMode(digit3, OUTPUT);
  pinMode(digit4, OUTPUT);

  pinMode(LedPin, OUTPUT);

  pinMode(A, INPUT_PULLUP);
  digitalWrite(A, HIGH);
  pinMode(B, INPUT_PULLUP);
  digitalWrite(B, HIGH);
  pinMode(C, INPUT_PULLUP);
  digitalWrite(C, HIGH);
  pinMode(D, INPUT_PULLUP);
  digitalWrite(D, HIGH);

  pinMode(Coil_1, OUTPUT);
  digitalWrite(Coil_1, HIGH); //закрыли замок
  pinMode(Coil_2, OUTPUT);
  digitalWrite(Coil_2, LOW); //отключили парогенератор


}

void loop()
{
  unsigned long startTime = millis();
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis > interval)
  {
    previousMillis = currentMillis;
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;
    digitalWrite(LedPin, ledState);
  }

  In_A = digitalRead(A);
  In_B = digitalRead(B);
  In_C = digitalRead(C);
  In_D = digitalRead(D);

  //A - правильно = LOW == соединено с землёй, разрыв - подтянут к питанию
  //B - правильно = LOW == соединено с землёй, разрыв - подтянут к питанию
  //C - правильно = LOW == соединено с землёй, разрыв - подтянут к питанию
  //D - правильно = LOW == соединено с землёй, разрыв - подтянут к питанию
  //если А или В и C или D собраны



  INPUTS = (((In_A << 2) + (In_B << 1) + (In_C)) * 0x07);
  switch (INPUTS)
  {
    case 0://(A = L) && (B = L) && (C = L) && (D = L))
      BOMB_config(250, 100, HIGH, HIGH, HIGH, HIGH);
      break;
    case 1://(A = L) && (B = L) && (C = L) && (D = H))
      BOMB_config(250, 1000, HIGH, HIGH, HIGH, HIGH);
      break;
    case 2://(A = L) && (B = L) && (C = H) && (D = L))
      BOMB_config(250, 1000, HIGH, HIGH, HIGH, HIGH);
      break;
    case 3://(A = L) && (B = L) && (C = H) && (D = H))
      BOMB_config(250, 1000, HIGH, HIGH, HIGH, HIGH);
      break;
    case 4://(A = L) && (B = H) && (C = L) && (D = L))
      BOMB_config(250, 1000, HIGH, HIGH, HIGH, HIGH);
      break;
    case 5://(A = L) && (B = H) && (C = L) && (D = H))
      BOMB_config(250, 1000, HIGH, HIGH, HIGH, HIGH);
      break;
    case 6://(A = L) && (B = H) && (C = H) && (D = L))
      BOMB_config(250, 1000, HIGH, HIGH, HIGH, HIGH);
      break;
    case 7://(A = L) && (B = H) && (C = H) && (D = H))
      BOMB_config(250, 1000, HIGH, HIGH, HIGH, HIGH);
      break;
    case 8://(A = H) && (B = L) && (C = L) && (D = L))
      BOMB_config(250, 1000, HIGH, HIGH, HIGH, HIGH);
      break;

  }








  Serial.println(start_num);

}
//---BOMB-CONFIG--------------------------
void BOMB_config (int blink_time, unsigned long Time_interval, int ledpin_state1, int ledpin_state2, int coil_1_state, int coil_2_state)
{
  unsigned long Time_previous_Millis = 0;
  unsigned long Time_current_Millis = millis();// прошлое значение времени милисекунд
  //Time_interval = 1000;//интервал в милисекундах (минута=60000)
  if (Time_current_Millis - Time_previous_Millis >= Time_interval)
  {
    setup_num -= 1;
    Time_previous_Millis = Time_current_Millis;
  }
  start_num = setup_num;

  if (start_num > 0)
  {
    num_min = start_num / 60;
    num_sec = start_num % 60;
    num_time = ((num_min * 100) + num_sec);
    displayNumber(num_time);
    digitalWrite(Coil_1, HIGH);
    digitalWrite(Coil_2, LOW);
  }
  if (start_num <= 0)
  {
    time = millis();
    while (millis() < time + blink_time)
    {
      displayNumber(0);
      digitalWrite(LedPin, ledpin_state1);
      digitalWrite(Coil_1, coil_1_state);
      digitalWrite(Coil_2, coil_2_state);
    }
    time = millis();
    while (millis() < time + blink_time)
    {
      lightNumber(10);
      digitalWrite(LedPin, ledpin_state2);
      digitalWrite(Coil_1, coil_1_state);
      digitalWrite(Coil_2, coil_2_state);
    }
  }
}

////---BOMB-ARM-----------------------------
//void BOMB_Arm()
//{
//  if (start_num > 0)
//  {
//    num_min = start_num / 60;
//    num_sec = start_num % 60;
//    num_time = ((num_min * 100) + num_sec);
//    displayNumber(num_time);
//    digitalWrite(Coil_1,HIGH);
//    digitalWrite(Coil_2,LOW);
//  }
//  if(start_num <= 0)
//  {
//    time = millis();
//    while(millis() < time + blink_time)
//    {
//      displayNumber(0);
//      digitalWrite(LedPin,HIGH);
//      digitalWrite(Coil_1,LOW);
//      digitalWrite(Coil_2,HIGH);
//    }
//    time=millis();
//    while(millis() < time + blink_time)
//    {
//      lightNumber(10);
//      digitalWrite(LedPin,HIGH);
//      digitalWrite(Coil_1,LOW);
//      digitalWrite(Coil_2,HIGH);
//    }
//  }
//}
//
////---BOMB-DISARM--------------------------
//void BOMB_Disarm()
//{
//  if (start_num > 0)
//  {
//    num_min = start_num / 60;
//    num_sec = start_num % 60;
//    num_time = ((num_min * 100) + num_sec);
//    time = millis();
//    while(millis() < time + blink_time)
//    {
//      displayNumber(num_time);
//      digitalWrite(LedPin,HIGH);
//      digitalWrite(Coil_1,LOW);
//      digitalWrite(Coil_2,LOW);
//    }
//    time=millis();
//    while(millis() < time + blink_time)
//    {
//      lightNumber(10);
//      digitalWrite(LedPin,LOW);
//      digitalWrite(Coil_1,LOW);
//      digitalWrite(Coil_2,LOW);
//    }
//  }
//  if(start_num <= 0)
//  {
//    time = millis();
//    while(millis() < time + blink_time)
//    {
//      displayNumber(0);
//      digitalWrite(LedPin,HIGH);
//      digitalWrite(Coil_1,LOW);
//      digitalWrite(Coil_2,HIGH);
//    }
//    time=millis();
//    while(millis() < time + blink_time)
//    {
//      lightNumber(10);
//      digitalWrite(LedPin,HIGH);
//      digitalWrite(Coil_1,LOW);
//      digitalWrite(Coil_2,HIGH);
//    }
//  }
//}
////---BOMB-x2time-ARM----------------------
//void BOMB_x2time_Arm()
//{
//  if (start_num > 0)
//  {
//    num_min = start_num / 60;
//    num_sec = start_num % 60;
//    num_time = ((num_min * 100) + num_sec);
//    displayNumber(num_time);
//    digitalWrite(Coil_1,HIGH);
//    digitalWrite(Coil_2,LOW);
//  }
//  if(start_num <= 0)
//  {
//    time = millis();
//    while(millis() < time + blink_time)
//    {
//      displayNumber(0);
//      digitalWrite(LedPin,HIGH);
//      digitalWrite(Coil_1,LOW);
//      digitalWrite(Coil_2,HIGH);
//    }
//    time=millis();
//    while(millis() < time + blink_time)
//    {
//      lightNumber(10);
//      digitalWrite(LedPin,HIGH);
//      digitalWrite(Coil_1,LOW);
//      digitalWrite(Coil_2,HIGH);
//    }
//  }
//}
//-----------------------------------------------------------------------------
void displayNumber(int toDisplay)
{
#define DISPLAY_BRIGHTNESS  200
#define DIGIT_ON  HIGH
#define DIGIT_OFF  LOW

  long beginTime = millis();

  for (int digit = 4 ; digit > 0 ; digit--)
  {
    switch (digit) {
      case 1:
        digitalWrite(digit1, DIGIT_ON);
        break;
      case 2:
        digitalWrite(digit2, DIGIT_ON);
        break;
      case 3:
        digitalWrite(digit3, DIGIT_ON);
        break;
      case 4:
        digitalWrite(digit4, DIGIT_ON);
        break;
    }
    lightNumber(toDisplay % 10);
    toDisplay /= 10;

    delayMicroseconds(DISPLAY_BRIGHTNESS);
    lightNumber(10);

    digitalWrite(digit1, DIGIT_OFF);
    digitalWrite(digit2, DIGIT_OFF);
    digitalWrite(digit3, DIGIT_OFF);
    digitalWrite(digit4, DIGIT_OFF);

  }
  while ( (millis() - beginTime) < 10) ;
}

void lightNumber(int numberToDisplay) {

#define SEGMENT_ON  LOW
#define SEGMENT_OFF HIGH

  switch (numberToDisplay) {

    case 0:
      digitalWrite(segA, SEGMENT_ON);
      digitalWrite(segB, SEGMENT_ON);
      digitalWrite(segC, SEGMENT_ON);
      digitalWrite(segD, SEGMENT_ON);
      digitalWrite(segE, SEGMENT_ON);
      digitalWrite(segF, SEGMENT_ON);
      digitalWrite(segG, SEGMENT_OFF);
      break;

    case 1:
      digitalWrite(segA, SEGMENT_OFF);
      digitalWrite(segB, SEGMENT_ON);
      digitalWrite(segC, SEGMENT_ON);
      digitalWrite(segD, SEGMENT_OFF);
      digitalWrite(segE, SEGMENT_OFF);
      digitalWrite(segF, SEGMENT_OFF);
      digitalWrite(segG, SEGMENT_OFF);
      break;

    case 2:
      digitalWrite(segA, SEGMENT_ON);
      digitalWrite(segB, SEGMENT_ON);
      digitalWrite(segC, SEGMENT_OFF);
      digitalWrite(segD, SEGMENT_ON);
      digitalWrite(segE, SEGMENT_ON);
      digitalWrite(segF, SEGMENT_OFF);
      digitalWrite(segG, SEGMENT_ON);
      break;

    case 3:
      digitalWrite(segA, SEGMENT_ON);
      digitalWrite(segB, SEGMENT_ON);
      digitalWrite(segC, SEGMENT_ON);
      digitalWrite(segD, SEGMENT_ON);
      digitalWrite(segE, SEGMENT_OFF);
      digitalWrite(segF, SEGMENT_OFF);
      digitalWrite(segG, SEGMENT_ON);
      break;

    case 4:
      digitalWrite(segA, SEGMENT_OFF);
      digitalWrite(segB, SEGMENT_ON);
      digitalWrite(segC, SEGMENT_ON);
      digitalWrite(segD, SEGMENT_OFF);
      digitalWrite(segE, SEGMENT_OFF);
      digitalWrite(segF, SEGMENT_ON);
      digitalWrite(segG, SEGMENT_ON);
      break;

    case 5:
      digitalWrite(segA, SEGMENT_ON);
      digitalWrite(segB, SEGMENT_OFF);
      digitalWrite(segC, SEGMENT_ON);
      digitalWrite(segD, SEGMENT_ON);
      digitalWrite(segE, SEGMENT_OFF);
      digitalWrite(segF, SEGMENT_ON);
      digitalWrite(segG, SEGMENT_ON);
      break;

    case 6:
      digitalWrite(segA, SEGMENT_ON);
      digitalWrite(segB, SEGMENT_OFF);
      digitalWrite(segC, SEGMENT_ON);
      digitalWrite(segD, SEGMENT_ON);
      digitalWrite(segE, SEGMENT_ON);
      digitalWrite(segF, SEGMENT_ON);
      digitalWrite(segG, SEGMENT_ON);
      break;

    case 7:
      digitalWrite(segA, SEGMENT_ON);
      digitalWrite(segB, SEGMENT_ON);
      digitalWrite(segC, SEGMENT_ON);
      digitalWrite(segD, SEGMENT_OFF);
      digitalWrite(segE, SEGMENT_OFF);
      digitalWrite(segF, SEGMENT_OFF);
      digitalWrite(segG, SEGMENT_OFF);
      break;

    case 8:
      digitalWrite(segA, SEGMENT_ON);
      digitalWrite(segB, SEGMENT_ON);
      digitalWrite(segC, SEGMENT_ON);
      digitalWrite(segD, SEGMENT_ON);
      digitalWrite(segE, SEGMENT_ON);
      digitalWrite(segF, SEGMENT_ON);
      digitalWrite(segG, SEGMENT_ON);
      break;

    case 9:
      digitalWrite(segA, SEGMENT_ON);
      digitalWrite(segB, SEGMENT_ON);
      digitalWrite(segC, SEGMENT_ON);
      digitalWrite(segD, SEGMENT_ON);
      digitalWrite(segE, SEGMENT_OFF);
      digitalWrite(segF, SEGMENT_ON);
      digitalWrite(segG, SEGMENT_ON);
      break;

    case 10:
      digitalWrite(segA, SEGMENT_OFF);
      digitalWrite(segB, SEGMENT_OFF);
      digitalWrite(segC, SEGMENT_OFF);
      digitalWrite(segD, SEGMENT_OFF);
      digitalWrite(segE, SEGMENT_OFF);
      digitalWrite(segF, SEGMENT_OFF);
      digitalWrite(segG, SEGMENT_OFF);
      break;
  }
}

[/code]

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Поясните подробнее что Вы переключаете, что Вы хотите сделать и что работает не так.

И ещё, каков смысл переменной StartTime В асмом начале функции loop()?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Да, кстати, как долго эта программа должна по идее работать без перезугрузки? Если час-день, то ничего, а если "вечно", то имейте в виду. что millis  переполняется и срасывается в ноль каждые 49 с копейками суток. При сбросе millis в 0 у Вас всё неминуемо сломается.

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Не сломается, не надо пугать. А вот в строке 308 ошибка, переменная beginTime должна быть unsigned long.
Про то, что что то где то переключается и т.п. я не понял тоже.

red.kaktus.37
red.kaktus.37 аватар
Offline
Зарегистрирован: 06.07.2015

не испугали, дяденьки :) работает час, программно мигает нулями при переходе через ноль, конечно все не ансигнед значения будут считаться в минуса вплоть до переполнения, но мигать один фиг будет нолями. меня не испугать. и да я в курсе про милз() и его ширину.

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

Про переключения:

пока на входе (условно пусть будет А) лог 1 (подтянут к + питания) - отсчёт времени нормальный, примерно равен стандартному течению времени (короче говоря раз в секунду вычетает секунду), как только Вход А прижимаем к земле, вуаля: таймер начинает отсчитывать время много быстрее, чем в стандартном режиме.

В данном случае по сути вопроса пофиг, что за входы\выходы и что есть управляющие сигналы, не могу для себя внятно вообразить как, вести отсчёт одного времени на два режима, мне думается это какие то закулисные игры со стеком пролетают мимо меня :) 

т.е.: допустим в момент переключения было 28 минут 15 секунд, таймер ускорился и досчитал до 11:20, в следующем переключении отсчёт будет вестись не с 28:15 а с 11:20. 

убрал из кода лишнее, прошу:

void BOMB_Arm()
{
  start_num = (setup_num - (millis()/1000)); 
  if (start_num > 0)
  {
    num_min = start_num / 60;
    num_sec = start_num % 60;
    num_time = ((num_min*100)+num_sec);
     displayNumber(num_time);
  }     
  if(start_num <= 0)
  {
    // reached zero, flash the display
    time = millis();
    while(millis() < time+200) 
    {
      displayNumber(0);
    }
    time=millis();    
    while(millis() < time+200) 
    {
      lightNumber(10);
    }
  }  
}

void BOMB_Disarm()
{
  start_num = (setup_num - 0);
  if (start_num > 0)
  {
    num_min = start_num / 60;
    num_sec = start_num % 60;
    num_time = ((num_min*100)+num_sec);
    time = millis();
    while(millis() < time+500) 
    {
      displayNumber(num_time);
    }
    time=millis();    
    while(millis() < time+500) 
    {
      lightNumber(10);
    }
  }
}

void BOMB_Duble_arm()
{
  start_num = (setup_num - (millis()/100 ));
  if (start_num > 0)
  {
    num_min = start_num / 60;
    num_sec = start_num % 60;
    num_time = ((num_min*100)+num_sec);
//    Serial.println(num_time);
    displayNumber(num_time);
  }     
  if(start_num <= 0)
  {
    time = millis();
    while(millis() < time+200) 
    {
      displayNumber(0);
    }
    time=millis();    
    while(millis() < time+200) 
    {
      lightNumber(10);
    }
  }  
}

отдельно подпрограммы работают как нужно.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Так для этого Вам надо значения времени хранить в собственном регистре, а не использовать регистр millis, который Вы не меняете.

Кстати, а что мешает воспользоваться честным таймером, безо всяких millis'ов? Тогда эта проблема просто не возникла бы.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

kisoft пишет:
Не сломается, не надо пугать.
За час (как написал ТС), конечно, не сломается. А вот при переходе счётчика millis  через ноль сломается ещё как.

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Задолбали!
Не ломается ничего!
Лешак уже два года обратно как доказал.

red.kaktus.37
red.kaktus.37 аватар
Offline
Зарегистрирован: 06.07.2015

ЕвгенийП пишет:

Так для этого Вам надо значения времени хранить в собственном регистре, а не использовать регистр millis, который Вы не меняете.

Значение времени хранится в переменной start_num а в  setup_num храню константу 3600 секунд. start_num = (setup_num - (millis()/1000)) т.е. каждую итерацию я вычитаю из 3600 текущее значение millis()/1000 ( делю на 1000 для получения секунд)

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

результат в миллсе постоянно инкрементируется не зависимо от манипуляций с делениями и прочим, соответственно каждый раз вычитая из 3600 энное количество миллсов /100 или /1000 я меняю всего-лишь частное значение  start_num. В самом первом сообщении я  прибег к такому варианту:

if (Time_current_Millis - Time_previous_Millis >= Time_interval)
  {
    setup_num -= 1;
    Time_previous_Millis = Time_current_Millis;
  }
  start_num = setup_num;

правда данный кусок кода не учитывает ускорения.

Вообщем запутался и начал ходить кругами, городя кучи ненужного кода.

ЕвгенийП пишет:

Кстати, а что мешает воспользоваться честным таймером, безо всяких millis'ов? Тогда эта проблема просто не возникла бы.

Проблема в том, что не понимаю пока, как в ардуине (у меня кстати нано на 328 меге) хоть косвенно воздействовать на таймер, а уж как его настроить вообще для меня сейчас тьма.

И кстати, раз уж я тут начал попрошайничать советов и пинков, скажите пожалуйста, где прописаны все типы переменных, привычнее использовать uint8_t и прочие... и ещё одно: нахре... почему всем переменным везде присваивают тип int ? это примудрость такая ардуины или просто исходя из объема памяти, нет глубокого смысла в оптимальном указании типов?

red.kaktus.37
red.kaktus.37 аватар
Offline
Зарегистрирован: 06.07.2015

И это... подскажите пожалуйста, как можно отредактировать первое сообщение, уж больно длинно оно, не увидел вначале спойлер, а теперь найти где редактировать не могу :)

bwn
Offline
Зарегистрирован: 25.08.2014

Типы данных , а инты, это извращенная фантазия писателей примеров. Они видят мегамегу с 32000 ног.

red.kaktus.37
red.kaktus.37 аватар
Offline
Зарегистрирован: 06.07.2015

про типы данных я в курсе, а где их править в библиотеках или может ещё где, не могу найти :( придётся дефайнить типо того:

typedef unsigned char 		uint8_t;
typedef unsigned int 		uint16_t;
typedef unsigned long int 	uint32_t;
typedef unsigned long long 	uint64_t;

typedef signed char 		int8_t;
typedef signed int 			int16_t;
typedef signed long int 	int32_t;
typedef signed long long 	int64_t;

typedef unsigned char		u_char;			// 0..255
typedef unsigned int		u_int;			// 0..65535
typedef unsigned long		u_long;			// 0..4294967295
typedef unsigned long long 	u_2long;			//0..18446744073709551615

typedef signed char			s_char;			// -128..127
typedef signed int			s_int;			// -32768..32767
typedef signed long			s_long;			// -2147483648..2147483647
typedef signed long long 	s_2long;			// -9223372036854775808..9223372036854775807

 

red.kaktus.37
red.kaktus.37 аватар
Offline
Зарегистрирован: 06.07.2015

кстати, может пригодится кому:

#ifndef GLOBAL_H
#define GLOBAL_H
//*****************************************************************************
// CPU clock speed
//#define F_CPU	16000000	// 16MHz
//#define F_CPU	14745000	// 14.745MHz
//#define F_CPU	12000000	// 12MHz 
//#define F_CPU	10000000	// 10MHz
#define F_CPU 9600000	// 9.6MHz (internal)
//define F_CPU	8000000	// 8MHz
//#define F_CPU	7372800	// 7.37MHz
//#define F_CPU	6000000	// 6MHz
//#define F_CPU 4800000	// 4.8MHz (internal)
//#define F_CPU	4000000	// 4MHz
//#define F_CPU	3686400	// 3.69MHz
//*****************************************************************************
#define dev_ver		0x01; //версия device x.xx
#define dev_sub_ver_hi	0x00;//
#define dev_sub_ver_lo	0x00; //
#define fw_ver		0x01 //версия firmware x.xx
#define fw_sub_ver_hi	0x00 //
#define fw_sub_ver_lo	0x00 //
//*****************************************************************************
enum {PRESSED,RELEASED};
enum {FALSE,TRUE};	
//*****************************************************************************
typedef unsigned char 		uint8_t;
typedef unsigned int 		uint16_t;
typedef unsigned long int 	uint32_t;
typedef unsigned long long 	uint64_t;

typedef signed char 		int8_t;
typedef signed int 			int16_t;
typedef signed long int 	int32_t;
typedef signed long long 	int64_t;

typedef unsigned char		u_char;			// 0..255
typedef unsigned int		u_int;			// 0..65535
typedef unsigned long		u_long;			// 0..4294967295
typedef unsigned long long 	u_2long;			//0..18446744073709551615

typedef signed char			s_char;			// -128..127
typedef signed int			s_int;			// -32768..32767
typedef signed long			s_long;			// -2147483648..2147483647
typedef signed long long 	s_2long;			// -9223372036854775808..9223372036854775807
//*****************************************************************************

//*****************************************************************************
#define ClearBit(reg, bit)		reg &= (0<<(bit))		// пример: ClearBit(PORTB, 1); //сбросить 1-й бит PORTB
#define SetBit(reg, bit)		reg |= (1<<(bit))			// пример: SetBit(PORTB, 3); //установить 3-й бит PORTB
void SetBitVal(u_char reg, u_char bit, u_char val)
{												// пример: SetBitVal(PORTB, 3, 1); 
 do 											//установить 3-й бит PORTB 
   {											// SetBitVal(PORTB, 2, 0);
    if ((val&1)==0) reg &= (~(1<<(bit)));		//сбросить 2-й бит PORTB
    else reg |= (1<<(bit));
   }
while(0);
};
#define BitIsClear(reg, bit)		((reg & (1<<(bit))) == 0)	//пример: if (BitIsClear(PORTB,1)) {...} //если бит очищен
#define BitIsSet(reg, bit)		((reg & (1<<(bit))) != 0)	//пример: if(BitIsSet(PORTB,2)) {...} //если бит установлен
#define InvBit(reg, bit)		reg ^= (1<<(bit))	//пример: InvBit(PORTB, 1); //инвертировать 1-й бит PORTB
//*****************************************************************************/*
//eeprom
#include <avr/eeprom.h>
uint8_t start_eep_addr = 0x01; //начало блока данных
uint8_t eeprom_data8 =		0x00;//
uint16_t eeprom_data16 =	0x0000;
uint32_t eeprom_data32 =	0x00000000;
void write_eeprom(void)//запись даных в EEPROM
{
//все записи ведутся от нуля, при написании программы ПЕРЕРАСЧИТЫВАТЬ
//адрес смещения ОБЯЗАТЕЛЬНО! иначе переменные "налезут" друг на друга
	eeprom_write_byte((uint8_t*)(start_eep_addr + 0), eeprom_data8);
	eeprom_write_word((uint16_t*)(start_eep_addr + 2), eeprom_data16);
	eeprom_write_dword((uint32_t*)(start_eep_addr + 4), eeprom_data32);
	_delay_us(50);
};
void read_eeprom(void)//считывание даных из EEPROM
{
//все записи ведутся от нуля, при написании программы ПЕРЕРАСЧИТЫВАТЬ 
//адрес смещения ОБЯЗАТЕЛЬНО! иначе переменные "налезут" друг на друга
	eeprom_data8 = eeprom_read_byte((uint8_t*)(start_eep_addr + 0));
	eeprom_data16 = eeprom_read_word((uint16_t*)(start_eep_addr + 2));
	eeprom_data32 = eeprom_read_dword((uint32_t*)(start_eep_addr + 4));
	_delay_us(50);
};
*/

#endif

SLOM
Offline
Зарегистрирован: 06.11.2014

  red.kaktus.37

интересный проект это у вас чтото типо игрушечной бомбы с отсоеденением проводов и ускорением времени? 
можно поподробней, получилось? где об этом подробней почитать? 
red.kaktus.37
red.kaktus.37 аватар
Offline
Зарегистрирован: 06.07.2015

SLOM

Именно так, проводки не те резанул и как в том анекдоте: одна нога здесь, другая там :) 

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

 вобщем то вот так и выглядит сие **мно

SLOM
Offline
Зарегистрирован: 06.11.2014

если несложно на мыло slom1@list.ru 

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

http://arduino.ru/forum/programmirovanie/led-matritsa-max7219-maxmatrixl...

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

trembo пишет:

Задолбали!
Не ломается ничего!
Лешак уже два года обратно как доказал.

Ну, раз лешак доказал, ... :)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

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

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

red.kaktus.37
red.kaktus.37 аватар
Offline
Зарегистрирован: 06.07.2015

ЕвгенийП

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

red.kaktus.37@gmail.com

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Сначала ссылки, читаем вот в таком порядке:

http://maxembedded.com/2011/06/introduction-to-avr-timers/
http://maxembedded.com/2011/06/avr-timers-timer0/
http://maxembedded.com/2011/06/avr-timers-timer1/
http://maxembedded.com/2011/06/avr-timers-timer2/
http://maxembedded.com/2011/07/avr-timers-ctc-mode/

Становится всё понятно, но кое-какие тонкости автор не рассмотрел, например, нигде не сказал, что таймер может быть просто нафиг отключён для экономии энергии и не показал как его включать. А кое-где пишет как принято в примерах, а не в серьёзных разработках, например, нагло вставляет sei() после инициализации таймера.

Но в целом, ссылки годные.

Некоторые из этих тонкостей, рассматриваются в мануале, который сейчас вышлю по почте.

Ну и, наконец, самый кошерный источник информации - datasheet контроллера ATMega328 - там на 650 страницах написано ВСЁ. Взять можно - http://www.atmel.com/images/Atmel-8271-8-bit-AVR-Microcontroller-ATmega48A-48PA-88A-88PA-168A-168PA-328-328P_datasheet_Complete.pdf

red.kaktus.37
red.kaktus.37 аватар
Offline
Зарегистрирован: 06.07.2015

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

[code]
uint8_t digit1 = 11; //Анод десятки минут
uint8_t digit2 = 10; //Анод единицы минут
uint8_t digit3 = 9; //Анод десятки секунд
uint8_t digit4 = 6; //Анод единицы секунд

uint8_t segA = 3; //Катод сегмента А
uint8_t segB = 2; //...
uint8_t segC = 7; //...
uint8_t segD = 8; //...
uint8_t segE = 12; //...
uint8_t segF = 4; //...
uint8_t segG = 5; //Катод сегмента G

uint8_t LedPin = 13; //помигиваем светодиодиком как в сурьёзных часиках

uint8_t A = 14; //
uint8_t B = 15; //
uint8_t C = 16; //
uint8_t D = 17; //

uint8_t Coil_1 = 18;//выход бомба обезврежена
uint8_t Coil_2 = 19;//выход бомба 3.14-зданула

int16_t setup_num = 3600; //
int16_t start_num;
uint8_t num_min;
uint8_t num_sec;
int16_t num_time;
uint16_t Blink_time = 500;
static uint16_t last_time;

uint16_t intererval = 500;
uint8_t ledState = LOW;
uint32_t previousMillis = 0;

uint8_t In_A;
uint8_t In_B;
uint8_t In_C;
uint8_t In_D;
uint8_t flag = LOW;

uint32_t time;

void setup() {

  pinMode(segA, OUTPUT);
  pinMode(segB, OUTPUT);
  pinMode(segC, OUTPUT);
  pinMode(segD, OUTPUT);
  pinMode(segE, OUTPUT);
  pinMode(segF, OUTPUT);
  pinMode(segG, OUTPUT);

  pinMode(digit1, OUTPUT);
  pinMode(digit2, OUTPUT);
  pinMode(digit3, OUTPUT);
  pinMode(digit4, OUTPUT);

  pinMode(LedPin, OUTPUT);

  pinMode(A, INPUT_PULLUP);
  digitalWrite(A, HIGH);
  pinMode(B, INPUT_PULLUP);
  digitalWrite(B, HIGH);
  pinMode(C, INPUT_PULLUP);
  digitalWrite(C, HIGH);
  pinMode(D, INPUT_PULLUP);
  digitalWrite(D, HIGH);

  pinMode(Coil_1, OUTPUT);
  digitalWrite(Coil_1, HIGH); //закрыли замок
  pinMode(Coil_2, OUTPUT);
  digitalWrite(Coil_2, LOW); //отключили парогенератор

}

void loop()
{
  uint32_t currentMillis = millis();
  if (currentMillis - previousMillis > intererval)
  {
    previousMillis = currentMillis;
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;
    digitalWrite(LedPin, ledState);
  }

  In_A = digitalRead(A);//A - замкнуть на землю        (изначально подтянут к питанию)
  In_B = digitalRead(B);//B - создать разрыв цепи      (изначально подтянут к питанию)
  In_C = digitalRead(C);//C - замкнуть на землю        (изначально подтянут к питанию)
  In_D = digitalRead(D);//D - создать разрыв цепи      (изначально подтянут к питанию)
  uint8_t inputs_state = (((In_A << 3) + (In_B << 2) + (In_C << 1) + (In_D)) * 0x0F);

  if (flag == LOW)
  {
    if (inputs_state == 0)
    {
      BOMB_Arm();
    }
    else
    {
      flag = HIGH;
      switch (inputs_state)
      {
        case 75:// - timer stop
          BOMB_Disarm();
          break;
        default:// - timer duble speed
          BOMB_x2time_Arm();
          break;
      }
    }
  }


  if (flag == HIGH)
  {
    switch (inputs_state)
    {
      case 75:// - timer stop
        BOMB_Disarm();
        break;
      default:// - timer duble speed
        BOMB_x2time_Arm();
        break;
    }
  }


}

//---BOMB-ARM-----------------------------
void BOMB_Arm()
{
  start_num = (setup_num - (millis() / 1000));
  if ((start_num > 0) && (start_num < 3600))
  {
    num_min = start_num / 60;
    num_sec = start_num % 60;
    num_time = ((num_min * 100) + num_sec);
    displayNumber(num_time);
    digitalWrite(Coil_1, HIGH);
    digitalWrite(Coil_2, LOW);
    last_time = start_num;
  }
  if ((start_num <= 0) || (start_num > 3600))
  {
    time = millis();
    while (millis() < time + Blink_time)
    {
      displayNumber(0);
      digitalWrite(LedPin, HIGH);
      digitalWrite(Coil_1, LOW);
      digitalWrite(Coil_2, HIGH);
    }
    time = millis();
    while (millis() < time + Blink_time)
    {
      lightNumber(10);
      digitalWrite(LedPin, HIGH);
      digitalWrite(Coil_1, LOW);
      digitalWrite(Coil_2, HIGH);
    }
  }
}

//---BOMB-DISARM--------------------------
void BOMB_Disarm()
{
  start_num = last_time;
  if ((start_num > 0) && (start_num < 3600))
  {
    num_min = start_num / 60;
    num_sec = start_num % 60;
    num_time = ((num_min * 100) + num_sec);
    time = millis();
    while (millis() < time + Blink_time)
    {
      displayNumber(num_time);
      digitalWrite(LedPin, HIGH);
      digitalWrite(Coil_1, LOW);
      digitalWrite(Coil_2, LOW);
    }
    time = millis();
    while (millis() < time + Blink_time)
    {
      lightNumber(10);
      digitalWrite(LedPin, LOW);
      digitalWrite(Coil_1, LOW);
      digitalWrite(Coil_2, LOW);
    }
  }
  if ((start_num <= 0) || (start_num > 3600))
  {
    time = millis();
    while (millis() < time + Blink_time)
    {
      displayNumber(0);
      digitalWrite(LedPin, HIGH);
      digitalWrite(Coil_1, LOW);
      digitalWrite(Coil_2, HIGH);
    }
    time = millis();
    while (millis() < time + Blink_time)
    {
      lightNumber(10);
      digitalWrite(LedPin, HIGH);
      digitalWrite(Coil_1, LOW);
      digitalWrite(Coil_2, HIGH);
    }
  }
}
//---BOMB-x2time-ARM----------------------
void BOMB_x2time_Arm()
{
  start_num = (setup_num - (millis() / 100));
  if ((start_num > 0) && (start_num < 3600))
  {
    num_min = start_num / 60;
    num_sec = start_num % 60;
    num_time = ((num_min * 100) + num_sec);
    displayNumber(num_time);
    digitalWrite(Coil_1, HIGH);
    digitalWrite(Coil_2, LOW);
    last_time = start_num;
  }
  if ((start_num <= 0) || (start_num > 3600))
  {
    time = millis();
    while (millis() < time + Blink_time)
    {
      displayNumber(0);
      digitalWrite(LedPin, HIGH);
      digitalWrite(Coil_1, LOW);
      digitalWrite(Coil_2, HIGH);
    }
    time = millis();
    while (millis() < time + Blink_time)
    {
      lightNumber(10);
      digitalWrite(LedPin, HIGH);
      digitalWrite(Coil_1, LOW);
      digitalWrite(Coil_2, HIGH);
    }
  }
}
//-----------------------------------------------------------------------------
void displayNumber(int16_t toDisplay)
{
#define DISPLAY_BRIGHTNESS  200
#define DIGIT_ON  HIGH
#define DIGIT_OFF  LOW

  uint32_t begintime = millis();

  for (uint16_t digit = 4 ; digit > 0 ; digit--)
  {
    switch (digit) {
      case 1:
        digitalWrite(digit1, DIGIT_ON);
        break;
      case 2:
        digitalWrite(digit2, DIGIT_ON);
        break;
      case 3:
        digitalWrite(digit3, DIGIT_ON);
        break;
      case 4:
        digitalWrite(digit4, DIGIT_ON);
        break;
    }
    lightNumber(toDisplay % 10);
    toDisplay /= 10;

    delayMicroseconds(DISPLAY_BRIGHTNESS);
    lightNumber(10);

    digitalWrite(digit1, DIGIT_OFF);
    digitalWrite(digit2, DIGIT_OFF);
    digitalWrite(digit3, DIGIT_OFF);
    digitalWrite(digit4, DIGIT_OFF);

  }
  while ( (millis() - begintime) < 10) ;
}

void lightNumber(uint16_t numberToDisplay) {

#define SEGMENT_ON  LOW
#define SEGMENT_OFF HIGH

  switch (numberToDisplay) {

    case 0:
      digitalWrite(segA, SEGMENT_ON);
      digitalWrite(segB, SEGMENT_ON);
      digitalWrite(segC, SEGMENT_ON);
      digitalWrite(segD, SEGMENT_ON);
      digitalWrite(segE, SEGMENT_ON);
      digitalWrite(segF, SEGMENT_ON);
      digitalWrite(segG, SEGMENT_OFF);
      break;

    case 1:
      digitalWrite(segA, SEGMENT_OFF);
      digitalWrite(segB, SEGMENT_ON);
      digitalWrite(segC, SEGMENT_ON);
      digitalWrite(segD, SEGMENT_OFF);
      digitalWrite(segE, SEGMENT_OFF);
      digitalWrite(segF, SEGMENT_OFF);
      digitalWrite(segG, SEGMENT_OFF);
      break;

    case 2:
      digitalWrite(segA, SEGMENT_ON);
      digitalWrite(segB, SEGMENT_ON);
      digitalWrite(segC, SEGMENT_OFF);
      digitalWrite(segD, SEGMENT_ON);
      digitalWrite(segE, SEGMENT_ON);
      digitalWrite(segF, SEGMENT_OFF);
      digitalWrite(segG, SEGMENT_ON);
      break;

    case 3:
      digitalWrite(segA, SEGMENT_ON);
      digitalWrite(segB, SEGMENT_ON);
      digitalWrite(segC, SEGMENT_ON);
      digitalWrite(segD, SEGMENT_ON);
      digitalWrite(segE, SEGMENT_OFF);
      digitalWrite(segF, SEGMENT_OFF);
      digitalWrite(segG, SEGMENT_ON);
      break;

    case 4:
      digitalWrite(segA, SEGMENT_OFF);
      digitalWrite(segB, SEGMENT_ON);
      digitalWrite(segC, SEGMENT_ON);
      digitalWrite(segD, SEGMENT_OFF);
      digitalWrite(segE, SEGMENT_OFF);
      digitalWrite(segF, SEGMENT_ON);
      digitalWrite(segG, SEGMENT_ON);
      break;

    case 5:
      digitalWrite(segA, SEGMENT_ON);
      digitalWrite(segB, SEGMENT_OFF);
      digitalWrite(segC, SEGMENT_ON);
      digitalWrite(segD, SEGMENT_ON);
      digitalWrite(segE, SEGMENT_OFF);
      digitalWrite(segF, SEGMENT_ON);
      digitalWrite(segG, SEGMENT_ON);
      break;

    case 6:
      digitalWrite(segA, SEGMENT_ON);
      digitalWrite(segB, SEGMENT_OFF);
      digitalWrite(segC, SEGMENT_ON);
      digitalWrite(segD, SEGMENT_ON);
      digitalWrite(segE, SEGMENT_ON);
      digitalWrite(segF, SEGMENT_ON);
      digitalWrite(segG, SEGMENT_ON);
      break;

    case 7:
      digitalWrite(segA, SEGMENT_ON);
      digitalWrite(segB, SEGMENT_ON);
      digitalWrite(segC, SEGMENT_ON);
      digitalWrite(segD, SEGMENT_OFF);
      digitalWrite(segE, SEGMENT_OFF);
      digitalWrite(segF, SEGMENT_OFF);
      digitalWrite(segG, SEGMENT_OFF);
      break;

    case 8:
      digitalWrite(segA, SEGMENT_ON);
      digitalWrite(segB, SEGMENT_ON);
      digitalWrite(segC, SEGMENT_ON);
      digitalWrite(segD, SEGMENT_ON);
      digitalWrite(segE, SEGMENT_ON);
      digitalWrite(segF, SEGMENT_ON);
      digitalWrite(segG, SEGMENT_ON);
      break;

    case 9:
      digitalWrite(segA, SEGMENT_ON);
      digitalWrite(segB, SEGMENT_ON);
      digitalWrite(segC, SEGMENT_ON);
      digitalWrite(segD, SEGMENT_ON);
      digitalWrite(segE, SEGMENT_OFF);
      digitalWrite(segF, SEGMENT_ON);
      digitalWrite(segG, SEGMENT_ON);
      break;

    case 10:
      digitalWrite(segA, SEGMENT_OFF);
      digitalWrite(segB, SEGMENT_OFF);
      digitalWrite(segC, SEGMENT_OFF);
      digitalWrite(segD, SEGMENT_OFF);
      digitalWrite(segE, SEGMENT_OFF);
      digitalWrite(segF, SEGMENT_OFF);
      digitalWrite(segG, SEGMENT_OFF);
      break;
  }
}

[/code]

 

red.kaktus.37
red.kaktus.37 аватар
Offline
Зарегистрирован: 06.07.2015

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

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

А почему странно? Контроллер плох или Вас смущает, что его уже на плату впаяли? 

Кстати, я отправил e-amil

red.kaktus.37
red.kaktus.37 аватар
Offline
Зарегистрирован: 06.07.2015

плюсы большие конечно - не задумываясь шимить выходы, ацпшить входы и прочее, но!

сам факт того, что я не могу без лазанья по всем либам определить время выполнения того или иного макроса, не вижу железных регистров и не могу извращаться, пусть с тем же таймером, без всяких лишних библиотек - вот что странно. да и объём кода... так что сложные проекты только сио вставками асма :) а побаловаться - ардуина )))

найти бы на неё пооолный мануал - не плохо было бы увидеть воочию, что можно вписать (типа того же sei() cli() nop() ) короче говоря, когда вникну полностью в ардуину, тогда и буду говорить точно, а пока - только странно и всё :)

 

на данный момент хотелось бы вот так писать: (пример под тиньку 13а 2 канала ацп -> шим с арифметическим усреднением результата на выходе шима)

/*
 * Tiny13_adc2pwm.c
 *
 * Created: 02.01.2013 16:16:01
 *  Author: kaktus
 */ 	

/****************************************************/
#include "global.h"
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
/****************************************************/


#define count_num 512; //количество замеров
#define count_shift 9; //расчёт сдвига от кол-ва замеров:
						//2^1=2 2^2=4 2^3=8 2^4=16
						//2^5=32 2^6=64 2^7=128 2^8=256
						//2^9=512 2^10=1024 2^11=2048 2^12=4096
						//2^13=8192 2^14= 2^15=16384 2^16=32768

//adc
uint32_t conversion_averaging_ADC3_Ch = 0;//накопитель для усреднения результата
uint8_t conversion_result = 0;//измерение получаем сюда
uint16_t conversion_count = count_num;//производим Х замеров, с последующим их сложением и сдвигом 

//pwm
uint8_t PWM_MIN = 255;
uint8_t PWM_MAX = 0
uint8_t PWM_State = 0;

//functional
enum { ON, OFF};

/****************************************************/

ISR(TIM0_OVF_vect)
{
	InvBit(PORTB,4);
};


ISR(ADC_vect)
{
	conversion_result = (ADC >> 8);
	if (conversion_count !=0)
	{
		conversion_averaging_ADC3_Ch += conversion_result;
		conversion_count--;
	};
};
/****************************************************/
void adc_conversion(void)
{
	ADMUX |= ((1<<MUX1)|(1<<MUX0));
	_delay_us(10);
	ADCSRA |= (1<<ADSC);
	while (ADIF == 0);
	_delay_us(1);
	return ADIF;
};
/****************************************************/
int main (void)
{
	cli();
		//		    RST       no use      ADC3_Ch      no use     PWM_ch2      PWM_ch1
		PORTB = (1<<PORTB5)|(0<<PORTB4)|(0<<PORTB3)|(0<<PORTB2)|(0<<PORTB1)|(0<<PORTB0);
		DDRB  = (1<<DDB5)  |(0<<DDB4)  |(0<<DDB3)  |(0<<DDB2)  |(0<<DDB1)  |(0<<DDB0);
//тупим много много
_delay_ms(500);
_delay_ms(500);
		
		//ADC initialize
		ACSR  = 0x80;
		ADCSRA = 0x00;
		ADMUX = (0<<REFS0)|(1<<ADLAR)|(1<<MUX1)|(1<<MUX0);//MUX=00-PB5(ADC0); 11-PB3(ADC3);
		ADCSRB = (0<<ACME)|(0<<ADTS2)|(0<<ADTS1)|(0<<ADTS0);
		ADCSRA = (1<<ADEN)|(0<<ADSC)|(0<<ADATE)|(0<<ADIF)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
		DIDR0 = (0<<ADC0D)|(0<<ADC2D)|(0<<ADC3D)|(0<<ADC1D);
		
		//FPWM WGM = 3 (TOP = 0xFF) 
		//37,500KHz
		//NON INVERT (COM0A = 2)
		TCCR0B = 0x00;
		OCR0A = PWM_MIN-1;
		OCR0B = PWM_MIN-1;
		TCNT0 = 0x00;

		//FAST PWM -> TOP = 0xFF
			TCCR0A = (1<<COM0A1)|(0<<COM0A0)|(1<<COM0B1)|(0<<COM0B0)|(1<<WGM01)|(1<<WGM00);
			TCCR0B = (0<<FOC0A)|(0<<FOC0B)|(0<<WGM02)|(0<<CS02)|(0<<CS01)|(1<<CS00);
		
		//Fase Correct PWM -> TOP = 0xFF
			//TCCR0A = (1<<COM0A1)|(0<<COM0A0)|(0<<COM0B1)|(0<<COM0B0)|(0<<WGM01)|(1<<WGM00);
			//TCCR0B = (0<<FOC0A)|(0<<FOC0B)|(0<<WGM02)|(0<<CS02)|(0<<CS01)|(1<<CS00);
		
		MCUCR = (0<<PUD)|(0<<ISC01)|(0<<ISC00);// 01 - any level change INTn
		TIMSK0 = (0<<OCIE0B)|(0<<OCIE0A)|(1<<TOIE0);//TIM0_COMPA_vect enable
		GIMSK = (0<<INT0)|(0<<PCIE); 
		PCMSK = (0<<PCINT5)|(0<<PCINT4)|(0<<PCINT3)|(0<<PCINT2)|(0<<PCINT1)|(0<<PCINT0);

		//RST		-PB5	VCC-	5V
		//ADC		-PB3	PB2-			
		//			-PB4	PB1-	PWM_2ch	
		//ground	-GND	PB0-	PWM_1ch
		
		//		    RST       no use      ADC3_Ch      no use     PWM_ch2      PWM_ch1
		PORTB = (1<<PORTB5)|(0<<PORTB4)|(1<<PORTB3)|(0<<PORTB2)|(0<<PORTB1)|(0<<PORTB0);
		DDRB  = (1<<DDB5)  |(1<<DDB4)  |(0<<DDB3)  |(0<<DDB2)  |(1<<DDB1)  |(1<<DDB0);

		CLKPR=0x80;
		CLKPR=0x00;
		
	sei();
/****************************************************/
	while (1)
	{
		adc_conversion();
		if (conversion_count == 0)
		{
			cli();

//расчёт сдвига от кол-ва замеров:
	//2^1=2 2^2=4 2^3=8 2^4=16 
	//2^5=32 2^6=64 2^7=128 2^8=256 
	//2^9=512 2^10=1024 2^11=2048 2^12=4096 
	//2^13=8192 2^14= 2^15=16384 2^16=32768

			conversion_averaging_ADC3_Ch >>= count_shift;
			conversion_averaging_ADC3_Ch &= 0x000000ff;
			PWM_State = conversion_averaging_ADC3_Ch;
			OCR0A = PWM_State;
			OCR0B = PWM_State;
			conversion_count = count_num;
			sei();
		};
		
	};
	return 1;
}

_______________________________

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

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

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

Шимить и АЦП-шить, так это в контроллере в железе, ардуина тут не при делах. А библиотеки - так пишите напрямую с железом, кто мешает.

Да, нет, контроллер как контроллер а на чём писать ... мне лично разницы нет. В ардуиине сидит полный С++, мало - есть ассемблер, не вижу проблемы.

SLOM
Offline
Зарегистрирован: 06.11.2014

red.kaktus.37 спасибо за код, скажите а какая схема у вас для него собрана? какие модули использованы? 

у меня вот такие: 

https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcTtyqn5_vD1t3EsbttTF_DOOnc3GqoM-WU-Yo-32yZpnpHkQRgllQ

http://ru.aliexpress.com/item/1pcs-MAX7219-dot-matrix-module-microcontro...

 

как на них сделать обратный отсчет, хочу сделать "гаситель звезд" :)

SLOM
Offline
Зарегистрирован: 06.11.2014
Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

Я думал они тут обычный таймер делают по заказу всяких Махмудов. А они тут Звезду Смерти разрабатывают

red.kaktus.37
red.kaktus.37 аватар
Offline
Зарегистрирован: 06.07.2015

SLOM

модуль собсно одни - ардуина нана %) индикаторы KEM-1106BR релюшки TRA1-12 дабы не нагружать usb порт, всё навесное кроме ардуины питается с 7805, ардуина кстати питается тож с неё через диод ( там на платке запаян) собсно всё. 

О_О а зачем Вам звёзды гасить? от них же свет и тепло :) нинада нам вечную ночь )))))))))))))

плату и схему в пикаде скину на мыло еси нужно

ЕвгенийП

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

SLOM
Offline
Зарегистрирован: 06.11.2014

в топку террористов, трансформеры рулят :)

SLOM
Offline
Зарегистрирован: 06.11.2014

red.kaktus.37 да это ненастоящий гаситель звезд :)

реквезит для детского праздника)

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

SLOM пишет:

red.kaktus.37 да это ненастоящий гаситель звезд :)

реквезит для детского праздника)


Вот врун блин. Звезды на детском празднике гасить собрался. Кого из звезд пригласили? Надеюсь вся Российская попса в списке, :)

red.kaktus.37
red.kaktus.37 аватар
Offline
Зарегистрирован: 06.07.2015

самое главное чтоб Киркоров и Пугачиха были их гасить нужно, пора им уже ))) 

Киркоров кстати это второе название болгарки xD киркоровка блин ))))))))))

SLOM
Offline
Зарегистрирован: 06.11.2014

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

Гаситель звёзд/"Жнец" (Solar harvester) - огромная установка, которая активируется, чтобы уничтожить какую-либо звезду и взять её энергию. Незаменима в случаях, если нет возможности использовать ресурсы Великой Искры. Создаётся трансформерами, как правило, на естественном спутнике той звезды, которая будет уничтожена. 

 

 

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

Да куда уж нам.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

SLOM, а что там за контроллер? ARM? AVR?

SLOM
Offline
Зарегистрирован: 06.11.2014

где там? у меня ардуино нано :)

вот думаю как на нем сделать обратный отсчет...

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Там - это в устройстве, изображённом на выложенном Вами фото:)

А что за проблемы обратным отсчётом? Там же типа ... два пальца.

SLOM
Offline
Зарегистрирован: 06.11.2014

ЕвгенийП пишет:

Там - это в устройстве, изображённом на выложенном Вами фото:)

А что за проблемы обратным отсчётом? Там же типа ... два пальца.

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

проблемы не с обратным отсчетом, а с тем что я не программист :) в этом вся и проблема :) 

моих знаний хватает только на поиски, и небольшую модернизацию готового кода :( 

у меня задача такая. на матрице, по типу... 

реализовать примерно следующее: 

вывод текстовой информации, в виде бегущей строки, для этого я уже наел подходящую библиотеку. 

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

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

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

 

п.с. в ходе мероприятия ни одна звезда не пострадает, Алла Борисовна и Филип Бедросович могут спать спокойно :)

 

red.kaktus.37
red.kaktus.37 аватар
Offline
Зарегистрирован: 06.07.2015

обратный отсчёт берите хотяб из моего примера -
void BOMB_Arm() - вставляете после цикла луп, там, где все подпрограммы, вызов BOMB_Arm() тыкаете в цикл после какого-то условия. переменные
используемые в подпрограмме так же переносите
либо в луп либо в сэтап либо в секцию
инициализации. setup_num выставляете час.
если больше часа, нужно добавлять пару строк по аналогии.
дальше пересылаете результат в сдвиговый регистр индикатора.
чтоб время тикало постоянно, но была возможность прервать вывод времени и пульнуть в сдвиг Ваш текст, поставьте к примеру флаг, прям

перед вызовом подпрограммы го проверили, если 0, то посчитали и не показали.

SLOM
Offline
Зарегистрирован: 06.11.2014

ваши слова как мед! на рану :)

в теории все просто, а вот на практике)