Объясните на пальцах по условию if где туплю ((

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

DetSimen пишет:

BOOM пишет:

Деда слился? Без "разрешения"? ))

Смысла в изращениях не вижу, я не настока владею этим вашим лживым С++ 

Абсурднее высказываний не читал! Но могу ошибаться. Не хотелось бы ошибаться, я ж на фруме не первый день... Деда, ты ж не новичек. Чего ломаешься? Минимум одно решение есть - его Евгений Петрович таит как "туза".

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016
volatile uint32_t count = 0;

void setup() {
Serial.begin(115200);
}

void loop() {
  count+=!!LED_BUILTIN;
  Serial.println(count);
  delay(1000);
}
volatile uint32_t count = 0;

void setup() {
Serial.begin(115200);
}

void loop() {
  count+=!0;
  Serial.println(count);
  delay(1000);
}
#define pin 0
volatile uint32_t count = 0;

void setup() {
Serial.begin(115200);
}

void loop() {
  count+=!pin;
  Serial.println(count);
  delay(1000);
}

 

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

Ну, вот, вернулся.

В общем, как-то так. Не особо извращённо, зато с защитой от ваших воровских наклонностей :-) - поменяете копирайт в строке №4 - ни хрена работать не будет.

typedef volatile uint8_t * vuc;

uint8_t copySign = "©"[1];
vuc copyright = (vuc)"(C) KakaSoft";

void setup(void) {
	Serial.begin(9600);
	Serial.println((char *)copyright);
	for (vuc c = copyright+1; *c; *copyright += (*c++ | 1) - 3);
}

void loop(void) {
	static uint16_t counter = 0;

	counter += *copyright-copySign;
	Serial.println(counter);
	delay(500);
}

а пока не поменяли, всё работает. Выдаёт

(C) KakaSoft
1
2
3
4
5
6
...

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

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

а пока не поменяли, всё работает. Выдаёт

тридцать три же мужика,
не хотят признать сынка,
пусть считается пока
сын полка )))

typedef volatile uint8_t * vuc;

uint8_t copySign = "©"[1];
vuc copyright = (vuc)"(C) KakaSoft √ modyfi UA6EM";

void setup(void) {
  Serial.begin(115200);
  Serial.println((char *)copyright);
  for (vuc c = copyright+1; *c; *copyright += (*c++ | 1) - 3);
}

void loop(void) {
  static uint16_t counter = 0;

  counter += *copyright-copySign;
  Serial.println(counter);
  delay(500);
}

 

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

Так ото ж!

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

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

Так ото ж!

а то )))
 

(C) KakaSoft √ modyfi UA6EM
33
66
99

 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

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

BOOM пишет:
сериал вроде как нельзя. Или можно? Ну только честно.
Не знаю, мне казалось, что можно - результат-то надо куда-то выводить, иначе как понять, что оно работает? Ну, нельзя так значит это решение "нещитова" :-(

Боюсь, если "никуда не выводить", оптимизатор все выкинет.

В общем, думаю, без Serial, SD, TFT или чего-то подобного скетч может быть урезан до нуля. По крайней мере "идеальным" оптимизатором.

Т.е. без Serial задача неразрешима.

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

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

Ну, вот, вернулся.

В общем, как-то так. Не особо извращённо, зато с защитой от ваших воровских наклонностей :-) - поменяете копирайт в строке №4 - ни хрена работать не будет.

typedef volatile uint8_t * vuc;

uint8_t copySign = "©"[1];
vuc copyright = (vuc)"(C) KakaSoft";

void setup(void) {
	Serial.begin(9600);
	Serial.println((char *)copyright);
	for (vuc c = copyright+1; *c; *copyright += (*c++ | 1) - 3);
}

void loop(void) {
	static uint16_t counter = 0;

	counter += *copyright-copySign;
	Serial.println(counter);
	delay(500);
}

а пока не поменяли, всё работает. Выдаёт

(C) KakaSoft
1
2
3
4
5
6
...

 

Проверено и работает!

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

ua6em пишет:

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

а пока не поменяли, всё работает. Выдаёт

тридцать три же мужика,
не хотят признать сынка,
пусть считается пока
сын полка )))

typedef volatile uint8_t * vuc;

uint8_t copySign = "©"[1];
vuc copyright = (vuc)"(C) KakaSoft √ modyfi UA6EM";

void setup(void) {
  Serial.begin(115200);
  Serial.println((char *)copyright);
  for (vuc c = copyright+1; *c; *copyright += (*c++ | 1) - 3);
}

void loop(void) {
  static uint16_t counter = 0;

  counter += *copyright-copySign;
  Serial.println(counter);
  delay(500);
}

Нирабатаит!

18:37:21.776 -> :	⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮

 

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

andriano пишет:

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

BOOM пишет:
сериал вроде как нельзя. Или можно? Ну только честно.
Не знаю, мне казалось, что можно - результат-то надо куда-то выводить, иначе как понять, что оно работает? Ну, нельзя так значит это решение "нещитова" :-(

Боюсь, если "никуда не выводить", оптимизатор все выкинет.

В общем, думаю, без Serial, SD, TFT или чего-то подобного скетч может быть урезан до нуля. По крайней мере "идеальным" оптимизатором.

Т.е. без Serial задача неразрешима.

Однако ж опыты выше это исключают.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

BOOM пишет:

Нирабатаит!

18:37:21.776 -> :	⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮

это у тебя совсем китайская ардуина попалась )))

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

ua6em пишет:

BOOM пишет:

Нирабатаит!

18:37:21.776 -> :	⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮

это у тебя совсем китайская ардуина попалась )))

Возможно, для тестов я использую дуину из поднебесной на Atmega168. К сожалению проверить на другой дуине не могу.(

А где +1 к каунту? )

Ну то есть - ниработаит! Минусую.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

всё можно, если знаешь как )))

PS к примеру строку 3 размаскировать
PPS а вообще познавательно, к примеру я не знал, что такой конструкцией можно сканкоды брать...

uint8_t copySign = 169;

 

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

ua6em пишет:

всё можно, если знаешь как )))

PS к примеру строку 3 размаскировать
PPS а вообще познавательно, к примеру я не знал, что такой конструкцией можно сканкоды брать...

uint8_t copySign = 169;

 

Не съезжай с темы, не работает твой код. Поясни, хотя бы...

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

 Воот. Рядом с Петровичем я ни на что, кроме "чучуть продвинутого делитанта" не претендую. :-)

Ибо нехрен...

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

BOOM пишет:

Не съезжай с темы, не работает твой код. Поясни, хотя бы...

код работает именно так как я его написал, то-есть с шагом 33

в оригинале в 9 строке от 170 отнимаем 169 )))

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

BOOM пишет:

andriano пишет:

Т.е. без Serial задача неразрешима.

Однако ж опыты выше это исключают.

Можете ткнуть пальчиком, какие именно опыты и что они исключают?

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

BOOM пишет:

Не съезжай с темы, не работает твой код. Поясни, хотя бы...

Так понятно?

typedef volatile uint8_t * vuc;
uint8_t copySign = 169; // "©"[1];
vuc copyright = (vuc)"(C) de ua6em ☺"; 

void setup(void) {
  Serial.begin(115200);
  Serial.println((char *)copyright);
  for (vuc c = copyright + 1; *c; *copyright += (*c++ | 1) - 3);
}

void loop(void) {
  static uint16_t counter = 0;
  counter += *copyright - copySign;
  Serial.println(counter);
  delay(500);
}

 

или так )))
 

typedef volatile uint8_t * vuc;

uint8_t copySign =  "©"[1];
vuc copyright = (vuc)"(C) de r6ead  ♦"; 

void setup(void) {
  Serial.begin(115200);
  Serial.println((char *)copyright);
  for (vuc c = copyright + 1; *c; *copyright += (*c++ | 1) - 3);
}

void loop(void) {
  static uint16_t counter = 0;
  counter += *copyright - copySign;
  Serial.println(counter);
  delay(500);
}

 

Kakmyc
Offline
Зарегистрирован: 15.01.2018

ua6em пишет:

всё можно, если знаешь как )))

PS к примеру строку 3 размаскировать
PPS а вообще познавательно, к примеру я не знал, что такой конструкцией можно сканкоды брать...

uint8_t copySign = 169;

 

Т.е. ты утверждаешь, что был не в курсе того, что в таблице символов каждый символ имеет свой порядковый номер ?
Или ты не знал что uint8_t это по сути своей char ?

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Kakmyc пишет:
ua6em пишет:

всё можно, если знаешь как )))

PS к примеру строку 3 размаскировать
PPS а вообще познавательно, к примеру я не знал, что такой конструкцией можно сканкоды брать...

uint8_t copySign = 169;

 

Т.е. ты утверждаешь, что был не в курсе того, что в таблице символов каждый символ имеет свой порядковый номер ? Или ты не знал что uint8_t это по сути своей char ?

я не знал, что второй байт кода можно взять так "©"[1]  ...

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

DetSimen пишет:

 Воот. Рядом с Петровичем я ни на что, кроме "чучуть продвинутого делитанта" не претендую. :-)

Ибо нехрен...

не, ну костыль сделать наверное бы смог! )))

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ЕвгенийП!
Есть надежда, что народ дождётся как в этой функции получается 170 )))
 

 for (vuc c = copyright + 1; *c; *copyright += (*c++ | 1) - 3);

PS существует 99 способов...100 профессор, 100 )))
 

typedef volatile uint8_t * vuc;

uint8_t copySign =  "©"[1];
vuc copyright = (vuc)"(C) de UA6EM"; 

void setup(void) {
  Serial.begin(115200);
  Serial.println((char *)copyright);
  for (vuc c = copyright + 1; *c; *copyright += (*c++ | 1) - 7);
  *copyright -=8;
}

void loop(void) {
  static uint16_t counter = 0;
  counter += *copyright - copySign;
  Serial.println(counter);
  delay(500);
}

 

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

ua6em пишет:

Есть надежда, что народ дождётся как в этой функции получается 170 )))

Да, хрен его знает. В этом цикле считается некая контрольная сумма копирайта (чтобы его нельзя было менять). Последовательность была такая, сначала я посмотрел код символа © (ну, типа прикольно именно его вычитать), а потом уже под него стал подбирать алгоритм расчёта контрольной суммы. Приблизительно прикинул как должно получиться, а константу 3 уже просто подобрал эмпирически.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

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

ua6em пишет:

Есть надежда, что народ дождётся как в этой функции получается 170 )))

Да, хрен его знает. В этом цикле считается некая контрольная сумма копирайта (чтобы его нельзя было менять). Последовательность была такая, сначала я посмотрел код символа © (ну, типа прикольно именно его вычитать), а потом уже под него стал подбирать алгоритм расчёта контрольной суммы. Приблизительно прикинул как должно получиться, а константу 3 уже просто подобрал эмпирически.

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

код то символа © двухбайтный, я даже подумать не мог, что второй байт можно взять такой конструкцией  c=©[1];

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

ua6em пишет:
второй байт можно взять такой конструкцией  c=©[1];
Такой нельзя :-)

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

невнимателен был, что есть то есть )))

Land
Offline
Зарегистрирован: 24.02.2022

Ну раз уж тут набежали такие гуру, может и вот с этим поможете?

[code]
/*
  HMC5883L Triple Axis Digital Compass. Compass Example.
  (c) 2014 by Korneliusz Jarzebski
*/

#include <StaticThreadController.h>
#include <Thread.h>
#include <ThreadController.h>
#include <Wire.h>
#include "HMC5883L.h"

ThreadController controll = ThreadController();
HMC5883L compass;

//My Thread (as a pointer)
Thread* myThread = new Thread();
//His Thread (not pointer)
Thread hisThread = Thread();

void mycompass (){
  Vector norm = compass.readNormalize();
  // Calculate heading
  float heading = atan2(norm.YAxis, norm.XAxis);
  // Convert to degrees
  float headingDegrees = heading * 180/M_PI; 
  // Output
  Serial.print(" Heading = ");
  Serial.print(heading);
  Serial.print(" Degress = ");
  Serial.print(headingDegrees);
  Serial.println();
  //delay(100);
}

void setup()
{
  Serial.begin(9600);
  // Initialize Initialize HMC5883L
  Serial.println("Initialize HMC5883L");
  while (!compass.begin())
  {
    Serial.println("Could not find a valid HMC5883L sensor, check wiring!");
    delay(500);
  }
  // Set measurement range
  compass.setRange(HMC5883L_RANGE_1_3GA);
  // Set measurement mode
  compass.setMeasurementMode(HMC5883L_CONTINOUS);
  // Set data rate
  compass.setDataRate(HMC5883L_DATARATE_15HZ);
  // Set number of samples averaged
  compass.setSamples(HMC5883L_SAMPLES_8);
  // Set calibration offset. See HMC5883L_calibration.ino
  compass.setOffset(0, 0);
  // Configure myThread
  hisThread.onRun(mycompass);
  hisThread.setInterval(100);
  // Adds both threads to the controller
  controll.add(myThread);
  controll.add(&hisThread); // & to pass the pointer to it
   //----------------TIMER 1 for interrupt frequency---------------------------------------
  TCCR1A = 0; // set entire TCCR1A register to 0
  TCCR1B = 0; // same for TCCR1B
  TCNT1  = 0; // initialize counter value to 0
  TIFR1 |= (1<<OCF1B); //сброс флагов прерывания timer1
  OCR1A = 2000; //      
  TCCR1B |= (0 << CS12) | (1 << CS11) | (0 << CS10); // Set CS12, CS11 and CS10 bits for 8 prescaler
  //TCCR1B = 0; // Stop Timer 1
  TCCR1B |= (1 << WGM12);// turn on CTC mode  
  //TIMSK1 |= (1 << OCIE1A);   // enable timer compare interrupt
  //sei(); // allow interrupts
}

void loop()
{
  controll.run();
}
[/code]

Если разрешаю прерывания по таймеру TIMSK1 |= (1 << OCIE1A);  enable timer compare interrupt, (стр. 71), то ломается вывод по I2C. Т.е. никаких показаний снять с HMC5883 невозможно. Комменчу прерывание -- прекрасно в монитор идут данные. 

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

А что по прерыванию таймера делается? Я «слёту» не понимаю. может в этом дело?)

Land
Offline
Зарегистрирован: 24.02.2022

По прерыванию таймера

//---------------------------------------------------------------------   
  ISR(TIMER1_COMPA_vect){
  timer_compare();
  }

висит сейчас просто пустая функция

void timer_compare() {
};

 

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Так может "второй заход"? А? )) Я в том смысле - нужно ВЕСЬ код выкладывать, а не куски, вызывающие еще больше вопросов...

nik182
Offline
Зарегистрирован: 04.05.2015

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

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

Land пишет:

Если разрешаю прерывания по таймеру TIMSK1 |= (1 << OCIE1A);  enable timer compare interrupt, (стр. 71), то ломается вывод по I2C. Т.е. никаких показаний снять с HMC5883 невозможно. Комменчу прерывание -- прекрасно в монитор идут данные. 

1. В коде нет обработчика прерываний. А значит, при первом же прерывании Ваш код просто зависает.

2. I2C сам работает на прерываниях и очень чувствителен к задержкам. Если Ваш код обработки прерываний (когда Вы его напишете) будет "хоть немного долгим", он будет ломать I2C.

Land
Offline
Зарегистрирован: 24.02.2022

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

1. В коде нет обработчика прерываний. А значит, при первом же прерывании Ваш код просто зависает.

2. I2C сам работает на прерываниях и очень чувствителен к задержкам. Если Ваш код обработки прерываний (когда Вы его напишете) будет "хоть немного долгим", он будет ломать I2C.

1.2. В прерывании вызывается функция. 

ISR(TIMER1_COMPA_vect){
  timer_compare();
  }
  void timer_compare (){
  digitalWrite(STEP_PIN, !digitalRead(STEP_PIN));
  STEP=++STEP;
  OCR1A = motorSpeed;
  if (STEP > TARGET_STEP){
  STEP=0; digitalWrite(DIR_PIN,!digitalRead(DIR_PIN));
  TARGET_STEP=TARGET_STEP+NULL_STEP; // КОСТЫЛЬ!
  FLAG_NULL=false;
   if (FLAG_Mode1) {
      TCCR1B &=~(1 << CS11); // Stop Timer 1
      digitalWrite(EN_PIN, OFF); // Disable driver in hardware
      FLAG_Mode1=false; // сброс флага "Режим 1"
    } else;
  }      
  }

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

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

Land пишет:
Или я неправильно понимаю?

1. Неправильно, Вы нигде не разрешали прерывания, потому они запрещены всё время.

2. Я искал гуглом библиотеки (т.к. Вы ссылок не дали), смотрел их, смотрел Ваш код, писал Вам комментарий. И всё это я делал лишь для того, чтобы потом услышать, что я смотрел не тот код, с которым проблема, что в нём есть что-то ещё, чего мне не показали? Я Вас правильно понял? И что, Вы всерьёз думаете, что после этого я кинусь изучать новый кусок кода, который Вы теперь соизволили дать? Чтобы ещё раз потерять время, а потом услышать, что там, на самом деле, ещё что-то было? Идите нахрен! Хотите получать ответы - учитесь задавать вопросы! 

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

#80 !!!!!!!!!!!!!!!!!

Land
Offline
Зарегистрирован: 24.02.2022

// ********************Author Land 20/02/2022*******land@tut.by*********
#include "Wire.h"
#include "HMC5883L.h"
#include "OneButton.h"

//***********************************************************************************************************
// Define pins
#define PIN_TO_NULL 3
#define EN_PIN    10  // LOW: Driver enabled. HIGH: Driver disabled
#define STEP_PIN  9  // Step on rising edge
//#define CORRECT_NULL_STEP 48 // коррекция в 3 шага на неточность установки нуля (4*16)
#define ANGLE1 44  //80 град / 1,8 ЭТО ЗНАЧЕНИЕ МОЖНО МЕНЯТЬ ДЛЯ ЗАДАНИЯ МАКИМАЛЬНОГО УГЛА ПОВОРОТА В РЕЖИМЕ
#define ANGLE2 100   //180 град / 1,8 ЭТО ЗНАЧЕНИЕ МОЖНО МЕНЯТЬ ДЛЯ ЗАДАНИЯ МАКИМАЛЬНОГО УГЛА ПОВОРОТА В РЕЖИМЕ
#define Mode1 14
#define Mode2 15
#define Mode3 16
#define Mode4 17
#define LEFT_BUTTON 4
#define RIGHT_BUTTON 5
#define ASIMUT_BUTTON 6 
#define MODE_BUTTON 7
#define Left HIGH
#define Right LOW
//#define ADC_PIN 22

HMC5883L compass;

OneButton buttonL(LEFT_BUTTON, true);
OneButton buttonR(RIGHT_BUTTON, true);
OneButton buttonA(ASIMUT_BUTTON, true);
OneButton buttonM(MODE_BUTTON,true);

//unsigned long pressStartTime;
char INCR=1;
int ANGLE;
int DIR_PIN= 8;
int GEAR_RATIO = 4; //коэфф. передачи шестерен
int MIN_SPEED = 19000; // ИЗМЕНЯТЬ С ОСТОРОЖНОСТЬЮ! 19000 = 2 об/мин ШД 64500 = 0,6 об/мин ШД
int MAX_SPEED = 1500; // ИЗМЕНЯТЬ С ОСТОРОЖНОСТЬЮ! 1500 = 20 об/мин ШД 935 = 40 об/мин ШД НЕ РЕКОМЕНДУЕТСЯ!
int TARGET_STEP=0;
int NULL_STEP = 0;
volatile bool DoR = Left; // направление вращения Left/Right
volatile word motorSpeed = MIN_SPEED;
bool FLAG_NULL=false;
volatile word adcReading;
int STEP = 1;
bool zero_setting = true;   
void adc_isr();
void timer_compare();   
volatile bool FLAG_Mode1 = false;    
bool ON = LOW;
bool OFF = HIGH;
float headingDegrees;             
//--------------------------------------------------------------------
  // ADC complete ISR
 ISR (ADC_vect)  {
  adc_isr();
  }
//---------------------------------------------------------------------   
  ISR(TIMER1_COMPA_vect){
  timer_compare();
  }
//---------------------------------------------------------------------
/*void mycompass (){
  Vector norm = compass.readNormalize();  
  float heading = atan2(norm.YAxis, norm.XAxis);  // Calculate heading  
  float headingDegrees = heading * 180/M_PI; // Convert to degrees
  Serial.print(" Degress = ");
  Serial.print(headingDegrees);
  Serial.println();
}*/
//---------------------------------------------------------------------

//--------------include all buttons here to be checked-----------------------------------  
  void checkTicks() {  
  buttonL.tick(); // just call tick() to check the state.
  buttonR.tick();
  buttonA.tick();
  buttonM.tick();
}  
//----------------------singleClickA------------------------------------------
void singleClickA() {     // действие по азимуту
    PORTC &=~0x0F; // сброс индикации
    Serial.println("singleClick(A) detected.");
//---------------Инициализация компасса-------------------------------------
  // Initialize Initialize HMC5883L
  Serial.println("Initialize HMC5883L");
  while (!compass.begin())
  {
    Serial.println("Could not find a valid HMC5883L sensor, check wiring!");
    digitalWrite(Mode4,!digitalRead(Mode4));
    delay(500);
  }
  compass.setRange(HMC5883L_RANGE_1_3GA);  // Set measurement range
  compass.setMeasurementMode(HMC5883L_CONTINOUS); // Set measurement mode
  compass.setDataRate(HMC5883L_DATARATE_75HZ); // Set data rate
  compass.setSamples(HMC5883L_SAMPLES_8); // Set number of samples averaged
  //compass.setOffset(0, 0);  // Set calibration offset. See HMC5883L_calibration.ino*/
  digitalWrite(Mode4,HIGH); // включили LED режим Азимут
   //  float asimut=headingDegrees;  //берем азимут
    int NEW_NULL = STEP;
} // 
//-----------------------singleClickM----------------------------------------
void singleClickM() {     // действие по выбору режима
  PORTC &=~0x0F; // сброс индикации
  digitalWrite(Mode2,HIGH); // включили LED режим 80 градусов
  //Serial.println("singleClick(M) detected.");
  FLAG_Mode1=false; // сброс флага "Режим 1"
  ANGLE = ANGLE1;
  TARGET_STEP=16000;
  Serial.println("ANGLE 80 Degress selected.");  
  while(FLAG_NULL){                               //  если двигались из NULL 
  digitalWrite(DIR_PIN,!digitalRead(DIR_PIN)); // сменили направление движения
  FLAG_NULL=false; // сброс флага
  }  
  digitalWrite(EN_PIN, ON);    // Enaable driver in hardware
  TCNT1=0;
  TCCR1B |= (0 << CS12) | (1 << CS11) | (0 << CS10) | (1 << WGM12); // Set CS12, CS11 and CS10 bits for 8 prescaler
  TIMSK1 |= (1 << OCIE1A);   // enable timer compare interrupt
} // 
//---------------------doubleClickM------------------------------------------
// this function will be called when the button was pressed 2 times in a short timeframe.
void doubleClickM() {
  PORTC &=~0x0F; // сброс индикации
  digitalWrite(Mode3,HIGH); // включили LED режим 180 градусов
  Serial.println("doubleClick(M) detected.");
  FLAG_Mode1=false; // сброс флага "Режим 1"
  ANGLE = ANGLE2;
  TARGET_STEP=16000;
  while(FLAG_NULL){                               //  если двигались из NULL 
  digitalWrite(DIR_PIN,!digitalRead(DIR_PIN)); // сменили направление движения
  FLAG_NULL=false; // сброс флага
  }
  Serial.println("ANGLE 180 Degress selected.");
  digitalWrite(EN_PIN, ON);    // Enaable driver in hardware
  TCNT1=0;
  TCCR1B |= (0 << CS12) | (1 << CS11) | (0 << CS10) | (1 << WGM12); // Set CS12, CS11 and CS10 bits for 8 prescaler
  TIMSK1 |= (1 << OCIE1A);   // enable timer compare interrupt
} // 
//---------------------singleClickL-------------------------------------
  // this function will be called when the button was pressed 1 time only.
void singleClickL() {
    PORTC &=~0x0F; // сброс индикации
    digitalWrite(EN_PIN, OFF);    // Disable driver in hardware 
    TCCR1B=0; // стоп таймера
    TCNT1=0;  // сброс счетчика таймера    
    digitalWrite(Mode1,HIGH);  // включили LED режим Ручной
    //digitalWrite(DIR_PIN, Left); // напрвление вращения ВЛЕВО        
    if (FLAG_NULL)TARGET_STEP = ANGLE2*GEAR_RATIO*16-NULL_STEP; // если идем от нуля, то устанавливаем целевой угол-корр.нуля
    else TARGET_STEP = ANGLE2*GEAR_RATIO*16;  // если идем к нулю, то устанавливаем целевой угол без коррекции
    ANGLE = ANGLE2; // макс. целевой угол = 180 град.
    Serial.println("singleClick(L) detected.");  
} // singleClickR
//----------------------singleClickR--------------------------------------------
void singleClickR() {
    PORTC &=~0x0F; // сброс индикации
    digitalWrite(EN_PIN, OFF);    // Disable driver in hardware
    TCCR1B=0; // стоп таймера
    TCNT1=0;  // сброс счетчика таймера
    digitalWrite(Mode1,HIGH); // включили LED режим Ручной     
    if (FLAG_NULL)TARGET_STEP = ANGLE2*GEAR_RATIO*16-NULL_STEP; // если идем от нуля, то устанавливаем целевой угол-корр.нуля
    else TARGET_STEP = ANGLE2*GEAR_RATIO*16;  // если идем к нулю, то устанавливаем целевой угол без коррекции
    ANGLE = ANGLE2; // макс. целевой угол = 180 град    
    Serial.println("singleClick(R) detected.");
} // singleClickR
//----------------------pressStart()L-------------------------------------------
// this function will be called when the button was held down for 1 second or more.
void pressStartL() {
  FLAG_Mode1=true; // флаг режима 1 для отключения вращения после достижения максимального угла поворота
  if(STEP==0&&DoR==Left){digitalWrite(EN_PIN, OFF);Serial.println("STOP");}else{
  if (digitalRead (DIR_PIN)); else // Если направление ВПРАВО -- 
  {digitalWrite(DIR_PIN, Left);INCR=-INCR;} // изменяем на ВЛЕВО
  DoR = Left;
  digitalWrite(EN_PIN, ON);    // Enaable driver in hardware
  TCNT1=0;  // сброс счетчика таймера
  TCCR1B |= (0 << CS12) | (1 << CS11) | (0 << CS10) | (1 << WGM12); // Set CS12, CS11 and CS10 bits for 8 prescaler
  TIMSK1 |= (1 << OCIE1A);   // enable timer compare interrupt 
  }
} // pressStart()L
//-----------------------pressStart()R----------------------------------------------------
void pressStartR() {
  FLAG_Mode1=true; // флаг режима 1 для отключения вращения после достижения максимального угла поворота
  if(STEP==0&&DoR==Right){digitalWrite(EN_PIN, OFF);Serial.println("STOP");}else{
  if (digitalRead (DIR_PIN)) {digitalWrite(DIR_PIN, Right); INCR=-INCR;} // если направление ВЛЕВО -- изменяем на ВПРАВО
  DoR = Right; 
  digitalWrite(EN_PIN, ON);    // Enaable driver in hardware
  TCNT1=0;  // сброс счетчика таймера
  TCCR1B |= (0 << CS12) | (1 << CS11) | (0 << CS10) | (1 << WGM12); // Set CS12, CS11 and CS10 bits for 8 prescaler
  TIMSK1 |= (1 << OCIE1A);   // enable timer compare interrupt
  }   
} // 
//----------------------pressStop()L---------------------------------------------
// this function will be called when the button was released after a long hold.
void pressStopL() {
  TCCR1B &=~(1 << CS11); // Stop Timer 1
  TCNT1=0;  // сброс счетчика таймера
  TIFR1 |= (1<<OCF1B)|(1<<OCF1A); //сброс флагов прерывания timer1
  digitalWrite(EN_PIN, OFF);    // Disable driver in hardware
  Serial.print("pressStop(L) = ");
  Serial.println(STEP);
} // 
//------------------------pressStop()R-----------------------------------------------------
// this function will be called when the button was released after a long hold.
void pressStopR() {
  TCCR1B &=~(1 << CS11); // Stop Timer 1
  TCNT1=0;  // сброс счетчика таймера
  TIFR1 |= (1<<OCF1B)|(1<<OCF1A); //сброс флагов прерывания timer1
  digitalWrite(EN_PIN, OFF);    // Disable driver in hardware
  Serial.print("pressStop(R) = ");
  Serial.println(STEP);
} // 
//-------------------------Обнуление------------------------------------------------------------
  void innull(){TARGET_STEP = ANGLE*GEAR_RATIO*16;//+CORRECT_NULL_STEP;
  STEP=NULL_STEP; FLAG_NULL=true; INCR=1; // вводим новое значени нулевого шага. устанавливаем шаг. |INCR|
  }
//--------------------------АЦП------------------------------------------------------------------
  void adc_isr (){
  adcReading = ADC;  
  motorSpeed = map(adcReading, 0, 1023, MIN_SPEED, MAX_SPEED);  // map it to a range from MIN_SPEED to MAX_SPEED
  }
//-------------------------Таймер-----------------------------------------------------------------
  void timer_compare (){
  digitalWrite(STEP_PIN, !digitalRead(STEP_PIN));
  //digitalWrite(Mode1, !digitalRead(Mode1));
  STEP=STEP+INCR;
  OCR1A = motorSpeed;
  if (STEP > TARGET_STEP){
  STEP=0; INCR=1;
  digitalWrite(DIR_PIN,!digitalRead(DIR_PIN));
  //Serial.println("REVERSE");
  TARGET_STEP=TARGET_STEP+NULL_STEP; // КОСТЫЛЬ!
  FLAG_NULL=false;
   if (FLAG_Mode1&&!FLAG_NULL) {
      TCCR1B &=~(1 << CS11); // Stop Timer 1
      digitalWrite(EN_PIN, OFF); // Disable driver in hardware
      //Serial.print("FLAG_STOP= ");
      //Serial.println(FLAG_NULL);
      FLAG_Mode1=false; // сброс флага "Режим 1"
    } else;
  }      
  }
//=======================================================================================================
void setup() {
  Serial.begin(115200);
  Serial.println("Start...");  
  // Prepare pins
  pinMode(EN_PIN, OUTPUT);
  pinMode(STEP_PIN, OUTPUT);
  pinMode(DIR_PIN, OUTPUT);
  pinMode(Mode1, OUTPUT);
  pinMode(Mode2, OUTPUT);
  pinMode(Mode3, OUTPUT);
  pinMode(Mode4, OUTPUT);
  digitalWrite(EN_PIN, OFF);   // Disable driver in hardware
  //--------------Прерывания--------------------------------------- 
  attachInterrupt(digitalPinToInterrupt(PIN_TO_NULL),innull,CHANGE);
  attachInterrupt(digitalPinToInterrupt(LEFT_BUTTON), checkTicks, CHANGE); 
  attachInterrupt(digitalPinToInterrupt(RIGHT_BUTTON), checkTicks, CHANGE);
  attachInterrupt(digitalPinToInterrupt(ASIMUT_BUTTON), checkTicks, CHANGE); 
  attachInterrupt(digitalPinToInterrupt(MODE_BUTTON),checkTicks,CHANGE);
  //-------------Функции обработки нажатий ----------------------------
  buttonL.attachClick(singleClickL);
  buttonL.setPressTicks(1000); // that is the time when LongPressStart is called
  buttonL.attachLongPressStart(pressStartL);
  buttonL.attachLongPressStop(pressStopL);

  buttonR.attachClick(singleClickR);
  buttonR.setPressTicks(1000); // that is the time when LongPressStart is called
  buttonR.attachLongPressStart(pressStartR);
  buttonR.attachLongPressStop(pressStopR);  

  buttonA.attachClick(singleClickA);  

  buttonM.attachClick(singleClickM);
  buttonM.attachDoubleClick(doubleClickM);
  /*//---------------Инициализация компасса-------------------------------------
  // Initialize Initialize HMC5883L
  Serial.println("Initialize HMC5883L");
  while (!compass.begin())
  {
    Serial.println("Could not find a valid HMC5883L sensor, check wiring!");
    digitalWrite(Mode4,!digitalRead(Mode4));
    delay(500);
  }
  compass.setRange(HMC5883L_RANGE_1_3GA);  // Set measurement range
  compass.setMeasurementMode(HMC5883L_CONTINOUS); // Set measurement mode
  compass.setDataRate(HMC5883L_DATARATE_75HZ); // Set data rate
  compass.setSamples(HMC5883L_SAMPLES_8); // Set number of samples averaged
  compass.setOffset(0, 0);  // Set calibration offset. See HMC5883L_calibration.ino*/
  //---------------Инициализация прерывания------------------------------------ 
  PCICR |= 1 << PCIE2;// Разрешение прерываний PCINT
  PCMSK0 |= (1<<PCINT20)|(1<<PCINT21)|(1<<PCINT22)|(1<<PCINT23); // Разрешение прерывания PCINT20...23)   
 //----------------Инициализация АЦП------------------------------------------- 
   cli();
  ADCSRA = 0;             // Сбрасываем регистр ADCSRA
  ADCSRB = 0;             // Сбрасываем регистр ADCSRB
  ADMUX |= (1 << REFS0);  // Задаем ИОН  
 // ADMUX |= (1 << ADLAR);  // Меняем порядок записи бит                         
  ADMUX &= ~ (1 << MUX3);
  ADMUX |= ((1 << MUX2) | (1 << MUX1) | (1 << MUX0));    // Выбираем пин A7  для преобразования
  // Устанавливаем предделитель - 4 (ADPS[2:0]=010)
  ADMUX &= ~ (1 << MUX3);
  ADMUX |= ((1 << MUX2) | (1 << MUX1) | (1 << MUX0));  //Битам ADPS1 и ADPS0 присваиваем нули /8
  ADCSRA |= (1 << ADATE); // Включаем автоматическое преобразование
  //ADCSRA |= (1 << ADIE);  // Разрешаем прерывания по завершении преобразования
  ADCSRA |= (1 << ADEN);  // Включаем АЦП
  ADCSRA |= (1 << ADSC);  // Запускаем преобразование
 //----------------TIMER 1 for interrupt frequency---------------------------------------
  TCCR1A = 0; // set entire TCCR1A register to 0
  TCCR1B = 0; // same for TCCR1B
  TCNT1  = 0; // initialize counter value to 0
  TIFR1 |= (1<<OCF1B); //сброс флагов прерывания timer1
  OCR1A = 2000; //      
  TCCR1B |= (1 << WGM12);// turn on CTC mode  
//------------------------------------------------------------------------------------------
  digitalWrite(EN_PIN, ON);    // Enable driver in hardware
  digitalWrite(DIR_PIN, Left);
}
//============================================================================================
void loop() {  
  Serial.println("DRV_STATUS = 0K");
  sei();
  while(zero_setting&&STEP){     
  digitalWrite(STEP_PIN, !digitalRead(STEP_PIN));
  delayMicroseconds(200);
  } zero_setting = false;
    STEP=1;
    NULL_STEP=58;  // вводим компенсацию в два шага на неточность установки нуля (4*16) КОСТЫЛЬ!
    digitalWrite(Mode1, HIGH); // LED режим 1  
    digitalWrite(EN_PIN, OFF);   // Disable driver in hardware
    Serial.println("DRIVER STOP");
    ADCSRA |= (1 << ADIE);  // Разрешаем прерывания по завершении преобразования
     
  while(1){
     buttonL.tick();
     buttonR.tick();
     buttonA.tick();
     buttonM.tick();
    
 /*   Vector norm = compass.readNormalize();  
  float heading = atan2(norm.YAxis, norm.XAxis);  // Calculate heading  
  float headingDegrees = heading * 180/M_PI; // Convert to degrees
  Serial.print(" Degress = ");
  Serial.print(headingDegrees);
  Serial.println();
     //delay(10);*/
 }
}

Я дико извиняюсь, но не предполагал, что кто-то захочет разбираться в трехстах строках чужого кода. Код поправлен, выброшен Thread. Сбой происходит при попытке инициализации HMC5883. Перестают работать управляющие кнопки. Но таймер с его функцией работать продолжает.

По библиотекам, сори, вот ссылки:

HMC5885L https://github.com/jarzebski/Arduino-HMC5883L

OneButton https://github.com/mathertel/OneButton

Thread https://github.com/ivanseidel/ArduinoThread

Wire.h из комплекта IDE Arduino

UPD. Работу HMC5883 рубило прерывание АЦП. Теперь осталось сообразить, как считывать результат АЦП без прерывания.

UUPD. С прерыванием, с делителем 64 (ADPS[2:0]=110) все заработало. Спасибо всем, пославшим нахрен.