Двухтональный генератор на ардуино

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

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

Код простой (немного лишнего, в дальнейшем убрать):

/*
 * Двухтональный генератор на базе ардуино нано
 */

unsigned long freq_1800;
unsigned long freq_2250;
int worked_1 = 0;
int worked_2 = 0;

void setup() {
  Serial.begin(115200);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(13, OUTPUT);
  digitalWrite(7,HIGH);
  freq_2250 = micros();
  digitalWrite(8,HIGH);
  freq_1800 = micros();
  digitalWrite(13,HIGH);
}

void loop() {
 if(micros() - freq_2250 >= 444){
  digitalWrite(7,!digitalRead(7));
  freq_2250 = micros();
   worked_2++;
    if(worked_2 == 2250){
    Serial.println("2250 -worked");
    worked_2 = 0; 
  }
 }
 if(micros() - freq_1800 >= 555){
  digitalWrite(8,!digitalRead(8));
  freq_1800 = micros();
  worked_1++;
  if(worked_1 == 1800){
    Serial.println("1800 -worked");
    worked_1 = 0;
    digitalWrite(13,!digitalRead(13)); 
  }
  
 }
 // Конец тела цикла
}

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

 

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

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

Добавлен код синхронизирующей частоты:
 

/*
 * Двухтональный генератор на базе ардуино нано (С) UA6EM
 * V-1.01 06.01.2019 (без использования таймеров)
 * V-1.02 07.01.2019 (Используя таймер 1 формируем частоту 2250 Гц на Pin10)
 * Prescaler: 1; MaxValue: 3555; Frequency: 2249.72Hz; Diff: 0.28Hz
 * http://arduino.ru/forum/programmirovanie/etyudy-dlya-nachinayushchikh-blink-i-bez-delay-i-bez-millis#comment-163979
 * 
 */

unsigned long freq_225;
unsigned long freq_1800;
unsigned long freq_2250;
byte flag_225 = 0;
byte delitel = 0;

enum Prescalers {
   PRESCALER_1 = 1, PRESCALER_8 = 2, PRESCALER_64 = 3, PRESCALER_256 = 4, PRESCALER_1024 = 5
};


// функция установки параметров таймера для выбранной частоты (в скобках номер таймера из калькулятора)
//     (1) Prescaler: 1; MaxValue: 4443; Frequency: 1800.18Hz; Diff: 0.18Hz
//     (2) Prescaler: 32; MaxValue: 138; Frequency: 1798.56Hz; Diff: 1.44Hz
//     (1) Prescaler: 1; MaxValue: 3555; Frequency: 2249.72Hz; Diff: 0.28Hz
//     (2) Prescaler: 32; MaxValue: 110; Frequency: 2252.25Hz; Diff: 2.25Hz
//     (1) Prescaler: 1; MaxValue: 35555; Frequency: 225.00Hz; Diff: 0.00Hz
// (0,1,2) Prescaler: 256; MaxValue: 138; Frequency: 224.82Hz; Diff: 0.18Hz

void set_Timer1(){   //Freq=2250Hz
   uint8_t prescaler = PRESCALER_1;
   uint16_t topValue = 3555;
   pinMode(10, OUTPUT);
   TCCR1A = 0x10;              // Инвертирование пина 10 по сравнению
   TCCR1B = 0x08 | prescaler;  // Установить СТС режим и делитель частоты
   OCR1A = topValue;           // установить TOP равным topValue
}

/*
void set_Timer2(){   //Freq=1800Hz
   uint8_t prescaler2 = 32;
   uint16_t topValue2 = 138;
   pinMode(11, OUTPUT);
   TCCR2A = 0x10;               // Инвертирование пина 11 по сравнению        ??? Уточнить
   TCCR2B = 0x08 | prescaler2;  // Установить СТС режим и делитель частоты    ??? Уточнить
   OCR2A = topValue2;           // установить TOP равным topValue             ??? Уточнить
}
*/

void start_Timer1(){
  TCCR1A = 0x10;              // Инвертирование пина 10 по сравнению
}

// Процедура для организации синхронизирующей частоты 225Гц от таймера частоты 2250
/*
void sync_Timer(){    if (digitalRead(10)==HIGH && flag_225 == 0 ){
    digitalWrite(13,HIGH);
        } else {
    digitalWrite(13,LOW);}
}
*/

// Процедура для организации синхронизирующей частоты 225Гц от частоты 2250hz (Pin9)
void sync_Timer(){ 
  if(delitel == 10){
    digitalWrite(13, !digitalRead(13));
    delitel = 0;
  }
}

void setup() {
  // Запустим таймер для частоты 2250 (Выход Pin 10)
  set_Timer1();
  start_Timer1();
  
  pinMode(7, OUTPUT);  // Freq 225Hz
  pinMode(8, OUTPUT);  // Freq 1800Hz
  pinMode(9, OUTPUT);  // Freq 2250Hz
  pinMode(13, OUTPUT); // Freq 225Hz Via SYNC Freq 2250Hz
  
  digitalWrite(13,HIGH);
  digitalWrite(9,HIGH);
  freq_2250 = micros();
  digitalWrite(8,HIGH);
  freq_1800 = micros();
  digitalWrite(7,HIGH);
  freq_225 = micros();
}

void loop() {
  if(micros() - freq_2250 >= 222){
  digitalWrite(9,!digitalRead(9));
  delitel++;
  freq_2250 = micros();
  }
  sync_Timer(); 
   
  if(micros() - freq_1800 >= 277){
  digitalWrite(8,!digitalRead(8));
  freq_1800 = micros();
  }

  if(micros() - freq_225 >= 2222){
  digitalWrite(7,!digitalRead(7));
  freq_225 = micros();
  }
}
/* END */

 

/*
 * Двухтональный генератор на базе ардуино нано
 */
#include "lgtx8p.h"
unsigned long freq_1;
unsigned long freq_18;
unsigned long freq_225;
unsigned long freq_1800;
unsigned long freq_2250;


void setup() {
 
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  
  freq_2250 = micros();
  freq_1800 = micros();
  freq_225 = micros();
  freq_18 = micros();
  freq_1 = micros();
  digitalWrite(7,HIGH);
   digitalWrite(8,HIGH);
    digitalWrite(9,HIGH);
     digitalWrite(10,HIGH);
      digitalWrite(11,HIGH);
  
}

void loop() {

  if(micros() - freq_1 >= 333333){
  digitalWrite(7,!digitalRead(7));
  freq_1 = micros();
    }
    
  if(micros() - freq_18 >= 22222){
  digitalWrite(8,!digitalRead(8));
  freq_18 = micros();
    }
    
  if(micros() - freq_225 >= 2222){
  digitalWrite(9,!digitalRead(9));
  freq_225 = micros();
    }
    
  if(micros() - freq_1800 >= 277){
  digitalWrite(10,!digitalRead(10));
  freq_1800 = micros();
   }
   
  if(micros() - freq_2250 >= 222){
  digitalWrite(11,!digitalRead(11));
  freq_2250 = micros();
    }
    
  digitalWrite(13, digitalRead(7));
    
 // Конец тела цикла
}

 

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

Как бы проанализировать аналоговую часть в LTSpace?
Нарисовать как-то удалось

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

Ну снимите АЧХ.

Какие еще идеи могут возникать при виде схемы ФНЧ.

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

andriano пишет:

Ну снимите АЧХ.

Какие еще идеи могут возникать при виде схемы ФНЧ.

Еще не паял, хотел проэмулировать, можно ли заменить на LM358

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

Почему нет, если фильтр на единицы кГц.

Только при чем здесь пайка? Я и предложил снять АЧХ на эмуляторе.

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

andriano пишет:

Почему нет, если фильтр на единицы кГц.

Только при чем здесь пайка? Я и предложил снять АЧХ на эмуляторе.

Так я и попросил дать ссылку на инструкцию, как это сделать, интуитивно сам не одолел )))
WDRAKULA этот эмулятор порекомендовал в ПЕСОЧНИЦЕ

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

Мой опыт работы с этой программой составил минут 20.

Но я так думаю, что, по общему правилу: порядок работы должен совпадать с таковым для снятия АЧХ в железе: подключить ко входу генератор, изменяя его частоту, смотреть амплитуду на выходе.

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

там же ссылка на статью ВалВола об элементарных способах работы.

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

wdrakula пишет:

там же ссылка на статью ВалВола об элементарных способах работы.

Почитал! Назвать сиё действо элементарным, язык не повернётся. Евгений Петрович был прав, это не для начинающих. Осталось спаять макетку и проверить подойдёт LM358 или нет )))

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

остановился на этом скетче:
 

/*
 * Двухтональный генератор на базе ардуино нано (С) UA6EM
 */
// функция установки параметров таймера для выбранной частоты (в скобках номер таймера из калькулятора)
//     (1) Prescaler: 1; MaxValue: 4443; Frequency: 1800.18Hz; Diff: 0.18Hz
//     (2) Prescaler: 32; MaxValue: 138; Frequency: 1798.56Hz; Diff: 1.44Hz
//     (1) Prescaler: 1; MaxValue: 3555; Frequency: 2249.72Hz; Diff: 0.28Hz
//     (2) Prescaler: 32; MaxValue: 110; Frequency: 2252.25Hz; Diff: 2.25Hz
//     (1) Prescaler: 1; MaxValue: 35555; Frequency: 225.00Hz; Diff: 0.00Hz
// (0,1,2) Prescaler: 256; MaxValue: 138; Frequency: 224.82Hz; Diff: 0.18Hz

enum Prescalers {
   PRESCALER_STOP = 0,
   PRESCALER_1 = 1, 
   PRESCALER_8 = 2, 
   PRESCALER_32 = 3, 
   PRESCALER_64 = 4, 
   PRESCALER_128 = 5, 
   PRESCALER_256 = 6, 
   PRESCALER_1024 = 7  
};

void set_Timer1(){   //Freq=2250Hz
   uint8_t prescaler = PRESCALER_1;
   uint16_t topValue = 3555;
   pinMode(10, OUTPUT);
   TCCR1A = 0x10;              // Инвертирование пина 10 по сравнению
   TCCR1B = 0x08 | prescaler;  // Установить СТС режим и делитель частоты
   OCR1A = topValue;           // установить TOP равным topValue
}

void set_Timer2(){   //Freq=1800Hz
   uint8_t prescaler2 = PRESCALER_32;
   uint8_t topValue2 = 138;
   pinMode(11, OUTPUT);
   TCCR2A = 0x42;               // Инвертирование пина 11 по сравнению       
   TCCR2B = 0x00 | prescaler2;  // Установить СТС режим и делитель частоты 
   OCR2A = topValue2;           // установить TOP равным topValue            
}

void start_Timer1(){
  TCCR1A = 0x10;              // Инвертирование пина 10 по сравнению
}
void start_Timer2(){
  TCCR2A = 0x42;              // Инвертирование пина 11 по сравнению
}

void setup() {
  // Запустим таймеры для частоты 2250 выход Pin 10 для частоты 1800 выход 11
  set_Timer1();
  start_Timer1();
  set_Timer2();
  start_Timer2();
}

void loop() { }

 

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

Какой смысл функций start*, если их код уже есть в функциях set* ? Или так хитро с таймерами работать нужно?

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

кое-что можно упростить конечно )))

PS без этих строк запускается только один таймер, пока не разбирался почему

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

По логике - нужно перенести их в конец функций set*, попробуй.

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Запуск/остановка таймера - это запись предделителя. Сразу не стартует - видимо в самом счетчике уже число больше чем в регистре сравнения. Приходится ждать полный круг. Надо обнулять сами счетчики !

Green
Offline
Зарегистрирован: 01.10.2015

Не нужно ничего переносить. Просто убрать старты за ненужностью. И будет работать.

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

Green пишет:

Не нужно ничего переносить. Просто убрать старты за ненужностью. И будет работать.

второй таймер не работал однако почему-то

Green
Offline
Зарегистрирован: 01.10.2015

А проверить?

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

Green пишет:

А проверить?

тут под руками осциллографа нет сейчас

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

и для платы Rasberry PI Pico под MicroPython v1.19 код будет ну очень простой:
PS c  пинов 22 и 21 сигнал объединить через переменный резистор, синхронизация на 20 пине,
PPS но джиттер под Питоном весьма приличный, сигнал на слух еще оценивал,
        частоты посмотрел на осциллографе, подправил ;- )))
 

from machine import Pin, Timer
tone1800 = Pin(21,Pin.OUT)
tim1 = Timer()
def tick1(timer):
    global tone1800 #1.8 килогерца
    tone1800.toggle()   
tim1.init(freq=1800*2, mode=Timer.PERIODIC, callback=tick1)

tone2250 = Pin(22,Pin.OUT)
tim2 = Timer()
def tick2(timer):
    global tone2250 #2.25 килогерца
    tone2250.toggle() 
tim2.init(freq=2250*2, mode=Timer.PERIODIC, callback=tick2)

sync = Pin(20,Pin.OUT)
tims = Timer()
def tics(timer):
    global sync #225 герц
    sync.toggle() 
tims.init(freq=225*2, mode=Timer.PERIODIC, callback=tics)

led = Pin(25,Pin.OUT)
tim = Timer()
def tick(timer):
    global led
    led.toggle()   
tim.init(freq=2.0, mode=Timer.PERIODIC, callback=tick)

 

b707
Offline
Зарегистрирован: 26.05.2017

че тебе надо то? инвертировать два пина с двумя разными частотами? - нафига это делать через прерывания?

Настрой два PWM таймера на две нужные частоты да и все, у Пики их 16 штук. Джиттера не будет вовсе

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

b707 пишет:

че тебе надо то? инвертировать два пина с двумя разными частотами? - нафига это делать через прерывания?

Настрой два PWM таймера на две нужные частоты да и все, у Пики их 16 штук. Джиттера не будет вовсе

это жеж на C++ а я тут потихоньку осваиваю Питон )))

PS в Питоне тоже можно через PWM вот и посмотрю, чуток попозжее

Переделал на PWM - сигнал мне нравится , теперь бы сравнить со скетчем на С++ ;-)))
 

import time
from machine import Pin, PWM, Timer

# Создаём объекты PWM
sync = PWM(Pin(19))
tone1800 = PWM(Pin(21))
tone2250 = PWM(Pin(22))

# Устанавливаем частоты PWM
sync.freq(225)
tone1800.freq(1800)
tone2250.freq(2250)

# Устанавливаем скважность
duty = 32768
sync.duty_u16(duty)
tone1800.duty_u16(duty)
tone2250.duty_u16(duty)

# Индикация работы тонального генератора
led = Pin(25,Pin.OUT)
tim = Timer()
def tick(timer):
    global led
    led.toggle()   
tim.init(freq=2.0, mode=Timer.PERIODIC, callback=tick)

 

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

А девкой всё же краше С библиотекой всё же проще )))
 

// Библиотека тут - //https://github.com/khoih-prog/RP2040_PWM


#define _PWM_LOGLEVEL_        3
#include "RP2040_PWM.h"


//creates pwm instance
RP2040_PWM * Tone2250;
RP2040_PWM * Tone1800;
RP2040_PWM * Tone225;

float freq1 = 2250;
float freq2 = 1800;
float freq3 = 225;
float dutyCycle = 50;


void setup()
{
  Tone2250 = new RP2040_PWM(22, freq1, dutyCycle);
  Tone1800 = new RP2040_PWM(21, freq2, dutyCycle);
  Tone225 = new RP2040_PWM(20, freq3, dutyCycle);

  Tone2250->setPWM(22, freq1, dutyCycle, true);
  Tone1800->setPWM(21, freq2, dutyCycle, true);
  Tone225->setPWM(20, freq3, dutyCycle, true); 
}

void loop(){}

 

b707
Offline
Зарегистрирован: 26.05.2017

ua6em пишет:

С библиотекой всё же проще )))

 

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

Вот только вопрос - понимаешь ли ты его, когда делаешь через библиотеку?

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

да что ж там понимать, пин, частота скважность )))
ЗЫ на удивление через библиотеку частоту устанавливает довольно точно

в это не въехал:
 

 // Tell GPIO 0 and 1 they are allocated to the PWM
    gpio_set_function(0, GPIO_FUNC_PWM);
    gpio_set_function(1, GPIO_FUNC_PWM);
 
    // Find out which PWM slice is connected to GPIO 0 (it's slice 0)
    uint slice_num = pwm_gpio_to_slice_num(0);
 
    // Set period of 4 cycles (0 to 3 inclusive)
    pwm_set_wrap(slice_num, 30);
    // Set channel A output high for one cycle before dropping
    pwm_set_chan_level(slice_num, PWM_CHAN_A, 1);
    // Set initial B output high for three cycles before dropping
    pwm_set_chan_level(slice_num, PWM_CHAN_B, 3);
    // Set the PWM running
    pwm_set_enabled(slice_num, true);
 
    // Note we could also use pwm_set_gpio_level(gpio, x) which looks up the
    // correct slice and channel for a given GPIO.

 

b707
Offline
Зарегистрирован: 26.05.2017

ua6em пишет:

в это не въехал:

сравни :)

https://arduino.ru/forum/apparatnye-voprosy/raspberry-pi-pico?page=5#com...

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

b707 пишет:

ua6em пишет:

в это не въехал:

сравни :)

https://arduino.ru/forum/apparatnye-voprosy/raspberry-pi-pico?page=5#com...

для меня это пока сложно, но так как нашёл библиотеку изучать сей вопрос буду неспешно...
Это ты напрасно недооцениваешь 64 градации ШИМ, для аналогового телевидения 10 градаций яркости было великолепно ))) (ТИТ-0249)

ShAlex13
Offline
Зарегистрирован: 19.01.2018

ua6em пишет:

А девкой всё же краше С библиотекой всё же проще )))
 

// Библиотека тут - //https://github.com/khoih-prog/RP2040_PWM


#define _PWM_LOGLEVEL_        3
#include "RP2040_PWM.h"


//creates pwm instance
RP2040_PWM * Tone2250;
RP2040_PWM * Tone1800;
RP2040_PWM * Tone225;

float freq1 = 2250;
float freq2 = 1800;
float freq3 = 225;
float dutyCycle = 50;


void setup()
{
  Tone2250 = new RP2040_PWM(22, freq1, dutyCycle);
  Tone1800 = new RP2040_PWM(21, freq2, dutyCycle);
  Tone225 = new RP2040_PWM(20, freq3, dutyCycle);

  Tone2250->setPWM(22, freq1, dutyCycle, true);
  Tone1800->setPWM(21, freq2, dutyCycle, true);
  Tone225->setPWM(20, freq3, dutyCycle, true); 
}

void loop(){}

 

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

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

да, выход на переменный резистор с двумя тумблерами, далее в качестве операционника LM358 (один корпус), всё как по схеме только значительно проще получается, только процессор болтается без дела, нехорошо, надо бы еще чему найти применение, надо подумать, к примеру сплиттер и индикатор CAT системы, тем более что к YAESU библиотека (благодаря DetSimen) написана...

ShAlex13
Offline
Зарегистрирован: 19.01.2018

Понятно, ждем дальнейшего развития девайса

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

ShAlex13 пишет:

Понятно, ждем дальнейшего развития девайса

мысли есть, что добавляем?

ShAlex13
Offline
Зарегистрирован: 19.01.2018

На ослике синусоиды "чистые" без лесенок?

Что с гармониками? по бокам не серит?

b707
Offline
Зарегистрирован: 26.05.2017

ShAlex13 пишет:

На ослике синусоиды "чистые" без лесенок?

откуда там синусоиды?

ShAlex13
Offline
Зарегистрирован: 19.01.2018

b707 пишет:

ShAlex13 пишет:

На ослике синусоиды "чистые" без лесенок?

откуда там синусоиды?

Имелось ввиду после операционника

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

ShAlex13 пишет:

b707 пишет:

ShAlex13 пишет:

На ослике синусоиды "чистые" без лесенок?

откуда там синусоиды?

Имелось ввиду после операционника

пока только цифру отлаживал... я тут как бы два проектика одновременно допиливаю, сканер 2400 - 2500 на ESP32 или RP2040,  и NRF24L01, сейчас выложу крайнюю версию...

Ослика у меня к сожалению нету, могу скинуть картинку только с Hantek DSO2D10 )))
ЗЫ (приму в дар ослика)

ShAlex13
Offline
Зарегистрирован: 19.01.2018

ua6em пишет:

Ослика у меня к сожалению нету, могу скинуть картинку только с Hantek DSO2D10 )))

ЗЫ (приму в дар Hantek DSO2D10)  :)

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

ShAlex13 пишет:

ua6em пишет:

Ослика у меня к сожалению нету, могу скинуть картинку только с Hantek DSO2D10 )))

ЗЫ (приму в дар Hantek DSO2D10)  :)

да мы тут все его по наводке BOOMа накупили

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

ua6em пишет:

и для платы Rasberry PI Pico под MicroPython v1.19 код будет ну очень простой:
PS c  пинов 22 и 21 сигнал объединить через переменный резистор, синхронизация на 20 пине,
PPS но джиттер под Питоном весьма приличный, сигнал на слух еще оценивал,
        частоты посмотрел на осциллографе, подправил ;- )))
 

from machine import Pin, Timer
tone1800 = Pin(21,Pin.OUT)
tim1 = Timer()
def tick1(timer):
    global tone1800 #1.8 килогерца
    tone1800.toggle()   
tim1.init(freq=1800*2, mode=Timer.PERIODIC, callback=tick1)

tone2250 = Pin(22,Pin.OUT)
tim2 = Timer()
def tick2(timer):
    global tone2250 #2.25 килогерца
    tone2250.toggle() 
tim2.init(freq=2250*2, mode=Timer.PERIODIC, callback=tick2)

sync = Pin(20,Pin.OUT)
tims = Timer()
def tics(timer):
    global sync #225 герц
    sync.toggle() 
tims.init(freq=225*2, mode=Timer.PERIODIC, callback=tics)

led = Pin(25,Pin.OUT)
tim = Timer()
def tick(timer):
    global led
    led.toggle()   
tim.init(freq=2.0, mode=Timer.PERIODIC, callback=tick)

 

Этот скетч работает безукоризненно, а вот со скетчем на С++ есть проблема