<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[forum.rcl-radio.ru &mdash; Переделки]]></title>
		<link>http://forum.rcl-radio.ru/index.php</link>
		<atom:link href="http://forum.rcl-radio.ru/extern.php?action=feed&amp;fid=10&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние темы раздела «forum.rcl-radio.ru».]]></description>
		<lastBuildDate>Fri, 23 Jan 2026 19:17:12 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[BD37534FV+LCD2004+энкодер+ИК пульт]]></title>
			<link>http://forum.rcl-radio.ru/viewtopic.php?id=727&amp;action=new</link>
			<description><![CDATA[<p>Здравствуйте, собрал этот проект, всё работает, не проверял только пульт. Хотелось бы добавить к нему модуль BT201 с управлением по uart. Чтобы при включении одного из трёх входов, пока не важно какого но к которому будет подключен модуль, появлялось четвёртое меню в котором первая строка это громкость, вторая- указывает на то, что включено, блютуз, USB или SD карта, третья и четвёртая это номер и название трека. Также нужно добавить кнопки воспроизведение-стоп, трек+, трек- и выбор блютуз, USB или SD карта.<br />Нужна помощь в написании скетча, сам не разберусь. И возможно ли это Вообще?<br />Всё железо на руках. Не знаю как прикрепить скетч который использую.</p><p><span class="attention-yellow"></span></p>]]></description>
			<author><![CDATA[null@example.com (lisiyivan)]]></author>
			<pubDate>Fri, 23 Jan 2026 19:17:12 +0000</pubDate>
			<guid>http://forum.rcl-radio.ru/viewtopic.php?id=727&amp;action=new</guid>
		</item>
		<item>
			<title><![CDATA[M62429 + OLED 128x32]]></title>
			<link>http://forum.rcl-radio.ru/viewtopic.php?id=724&amp;action=new</link>
			<description><![CDATA[<div class="codebox"><pre><code>// энкодер
#define ENC_DT       9
#define ENC_CLK      8
#define ENC_SW       10

// ИК датчик
#define IR           5

// кнопки управления
#define POWER_BUTTON    3
#define MUTE_BUTTON     4

// выход управления standby
#define STANDBY_OUT     13

// M62429 
#define CLK        11
#define DATA       12

// коды кнопок ИК пульта
#define MENU      0x2FDB24D // button encoder
#define UP        0x2FDD02F // &gt;&gt;&gt;
#define DW        0x2FD32CD // &lt;&lt;&lt;
#define POWER_IR  0x2FD00FF // POWER
#define MUTE_IR   0x2FDB04F // MUTE

#include &lt;Wire.h&gt; 
#include &lt;U8glib.h&gt;             // https://github.com/olikraus/u8glib/
#include &lt;Encoder.h&gt;            // http://rcl-radio.ru/wp-content/uploads/2019/05/Encoder.zip    
#include &lt;EEPROM.h&gt;
#include &lt;MsTimer2.h&gt;           // http://rcl-radio.ru/wp-content/uploads/2018/11/MsTimer2.zip       
#include &lt;boarddefs.h&gt;          // входит в состав библиотеки IRremote
#include &lt;IRremote.h&gt;           // http://rcl-radio.ru/wp-content/uploads/2019/06/IRremote.zip
#include &lt;M62429.h&gt;             // http://rcl-radio.ru/wp-content/uploads/2026/01/M62429.zip

 U8GLIB_SSD1306_128X32 u8g(U8G_I2C_OPT_NONE);  // I2C / TWI 
 IRrecv irrecv(IR);
 Encoder myEnc(ENC_DT, ENC_CLK);
 decode_results ir; 
 

 extern uint8_t SmallFont[],BigNumbers[];
 long times,oldPosition  = -999,newPosition;
 int vol,balans,bass,treb,in,menu;
 bool mute=0,gr1,gr2,w,w1,power=0;

 void setup(){
  Wire.begin();
  irrecv.enableIRIn();
  Serial.begin(9600);
  MsTimer2::set(3, to_Timer);MsTimer2::start();
  if(EEPROM.read(100)!=0){for(int i=0;i&lt;101;i++){EEPROM.update(i,0);}}// очистка памяти при первом включении  
  pinMode(POWER_BUTTON,INPUT_PULLUP);
  pinMode(MUTE_BUTTON,INPUT_PULLUP);
  pinMode(STANDBY_OUT,OUTPUT); 

 u8g.firstPage(); do {
  u8g.setFont(u8g_font_profont29r);u8g.drawStr(5,25,&quot;M62429&quot;); 
  }while( u8g.nextPage() );

  delay(3000);
  digitalWrite(STANDBY_OUT,LOW);
  vol = EEPROM.read(0);balans = EEPROM.read(3)-8;
  audio(); 
 }

 void loop(){
  // IR ////////////////////////////////////////
  if ( irrecv.decode( &amp;ir )) {Serial.print(&quot;0x&quot;);Serial.println( ir.value,HEX);irrecv.resume();times=millis();w=1;}// IR приемник - чтение, в мониторе порта отображаются коды кнопок
  if(ir.value==0){gr1=0;gr2=0;}// запрет нажатий не активных кнопок пульта  
  
 if(power==0){ 
 if(digitalRead(ENC_SW)==LOW || ir.value==MENU){menu++;cl();delay(200);times=millis();w1=1;w=1;if(menu&gt;1){menu=0;}} // меню


 if((digitalRead(MUTE_BUTTON)==LOW || ir.value==MUTE_IR)&amp;&amp; mute==0){mute=1;cl();times=millis();w1=1;w=1;mute_conf();
 u8g.firstPage(); do {u8g.setFont(u8g_font_profont29r);u8g.drawStr(25,25,&quot;MUTE&quot;);}while( u8g.nextPage() );delay(300);menu=100;} // mute on 

 if((digitalRead(MUTE_BUTTON)==LOW || ir.value==MUTE_IR)&amp;&amp; mute==1){mute=0;cl();times=millis();w1=1;w=1;audio();
 delay(300);menu=0;} // mute off 
 }

 if((digitalRead(POWER_BUTTON)==LOW || ir.value==POWER_IR)&amp;&amp; power==0){power=1;cl();times=millis();w1=1;w=1;mute_conf();digitalWrite(STANDBY_OUT,HIGH);
 u8g.firstPage(); do {u8g.setFont(u8g_font_profont29r);u8g.drawStr(10,25,&quot;STANDBY&quot;);}while( u8g.nextPage() );delay(2000);menu=100;
 u8g.firstPage(); do {}while( u8g.nextPage() );} // power on 

 if((digitalRead(POWER_BUTTON)==LOW || ir.value==POWER_IR)&amp;&amp; power==1){power=0;cl();times=millis();w1=1;w=1;audio();digitalWrite(STANDBY_OUT,LOW);delay(300);menu=0;} // power off 
 
  
//////// VOLUME //////////////////////////////////////////////////////////////////////////////////////////////////////////////  
  if(menu==0){
   if(newPosition != oldPosition){oldPosition = newPosition;if(newPosition&gt;1){newPosition=1;}if(newPosition&lt;-1){newPosition=-1;}
   vol=vol+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;vol_func();audio();}
 
   if(ir.value==UP){vol++;gr1=1;gr2=0;cl();times=millis();w=1;w1=1;vol_func();audio();}// кнопка &gt; 
   if(ir.value==0xFFFFFFFF and gr1==1){vol++;gr2=0;cl();times=millis();w=1;w1=1;vol_func();audio();}// кнопка &gt;&gt;&gt;&gt;&gt;&gt;
   if(ir.value==DW){vol--;gr1=0;gr2=1;cl();times=millis();w=1;w1=1;vol_func();audio();}// кнопка &lt;
   if(ir.value==0xFFFFFFFF and gr2==1){vol--;gr1=0;cl();times=millis();w=1;w1=1;vol_func();audio();}// кнопка &lt;&lt;&lt;&lt;&lt;&lt;
 
  if(w==1){w=0;
 // Serial.println(63-vol+balans);
  u8g.firstPage();  
   do {
  u8g.setFont(u8g_font_profont12r);u8g.drawStr(0,8,&quot;VOLUME&quot;);
  u8g.setFont(u8g_font_profont29r); u8g.setPrintPos(95, 24);u8g.print(vol-8);
  for(int v_pos=0; v_pos&lt;(75-8)*1.3;v_pos+=4){u8g.drawBox(v_pos+0,16, 2, 1);}
  for(int v_pos=0; v_pos&lt;(vol-8)*1.3;v_pos+=4){u8g.drawBox(v_pos+0,18, 2, 9);}
  for(int v_pos=0; v_pos&lt;(75-8)*1.3;v_pos+=4){u8g.drawBox(v_pos+0,28, 2, 1);}
   } while( u8g.nextPage() );
  }}

///////// BALL /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  if(menu==1){
   if(newPosition != oldPosition){oldPosition = newPosition;if(newPosition&gt;1){newPosition=1;}if(newPosition&lt;-1){newPosition=-1;}
   balans=balans+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;ball_func();audio();}

   if(ir.value==UP){balans++;gr1=1;gr2=0;ir.value=0;times=millis();w=1;w1=1;ball_func();audio();}// кнопка &gt; 
   if(ir.value==DW){balans--;gr1=0;gr2=1;ir.value=0;times=millis();w=1;w1=1;ball_func();audio();}// кнопка &lt;
 
  if(w==1){w=0;
 // Serial.println(83-vol+balans);
 // Serial.println(83-vol-balans);
  u8g.firstPage();  
   do {
  u8g.setFont(u8g_font_profont12r);u8g.drawStr(0,8,&quot;BALANCE&quot;);
  u8g.setFont(u8g_font_profont29r); 
  if(balans&gt;=0){u8g.setPrintPos(112, 24);u8g.print(balans);u8g.drawStr(95,24,&quot;+&quot;);}
  else{u8g.setPrintPos(95, 24);u8g.print(balans);}

  for(int v_pos=0; v_pos&lt;(12-1)*8;v_pos+=4){u8g.drawBox(v_pos+0,16, 2, 1);}
  const int SCREEN_WIDTH = 84; 
  u8g.drawBox(43,18, 1, 9);// 0 dB
  if(balans &gt;= 0){for(int v_pos=0; v_pos&lt;(balans*4);v_pos+=4){u8g.drawBox(v_pos+48,18, 2, 9);}} 
  else{for(int v_pos=SCREEN_WIDTH-48; v_pos&gt;(SCREEN_WIDTH-(abs(balans)*4)-48); v_pos-=4){u8g.drawBox(v_pos,18, 2, 9);}}
  for(int v_pos=0; v_pos&lt;(12-1)*8;v_pos+=4){u8g.drawBox(v_pos+0,28, 2, 1);}
  
   } while( u8g.nextPage() );
  }}
  

////////////// EEPROM /////////////////////////////////////////////////////////////////////  
  if(millis()-times&gt;5000 &amp;&amp; w1==1 &amp;&amp; power==0 &amp;&amp; mute==0){
     EEPROM.update(0,vol);EEPROM.update(3,balans+8);
     menu=0;w1=0;w=1;myEnc.write(0);}
  }

 
void to_Timer(){newPosition = myEnc.read()/4;} 
void audio(){
setVolume (CLK,DATA,0,0,83-vol+balans); 
setVolume (CLK,DATA,0,1,83-vol-balans);
/* pin CLK
   pin DATA
   0 - по одному каналу, 1 - оба вместе
   0 ПК 1 ЛК
   83 ... 0 громкость 83 = -83 дБ */  
}

void mute_conf(){
setVolume (CLK,DATA,0,0,84); 
setVolume (CLK,DATA,0,1,84);
  }


void vol_func(){if(vol&gt;75){vol=75;}if(vol&lt;=8){vol=8;}} // int 0 ... int 79 
void ball_func(){if(balans&gt;8){balans=8;}if(balans&lt;=-8){balans=-8;}}
void cl(){ir.value=0;delay(200);} </code></pre></div>]]></description>
			<author><![CDATA[null@example.com (liman324)]]></author>
			<pubDate>Mon, 05 Jan 2026 11:35:42 +0000</pubDate>
			<guid>http://forum.rcl-radio.ru/viewtopic.php?id=724&amp;action=new</guid>
		</item>
		<item>
			<title><![CDATA[PT2257 + OLED 128x32]]></title>
			<link>http://forum.rcl-radio.ru/viewtopic.php?id=723&amp;action=new</link>
			<description><![CDATA[<p><span class="postimg"><img src="http://forum.rcl-radio.ru/uploads/images/2026/01/233aaa5371e0f4f322498c18039693e8.png" alt="http://forum.rcl-radio.ru/uploads/images/2026/01/233aaa5371e0f4f322498c18039693e8.png" /></span> </p><br /><p><span class="postimg"><img src="http://forum.rcl-radio.ru/uploads/images/2026/01/c9200d50cc2d87a6afa7bca554b03f96.png" alt="http://forum.rcl-radio.ru/uploads/images/2026/01/c9200d50cc2d87a6afa7bca554b03f96.png" /></span> </p><br /><div class="codebox"><pre><code>// энкодер
#define ENC_DT       9
#define ENC_CLK      8
#define ENC_SW       10

// ИК датчик
#define IR           12

// кнопки управления
#define POWER_BUTTON    3
#define MUTE_BUTTON     4

// выход управления standby
#define STANDBY_OUT     13

// коды кнопок ИК пульта
#define MENU      0x2FDB24D // button encoder
#define UP        0x2FDD02F // &gt;&gt;&gt;
#define DW        0x2FD32CD // &lt;&lt;&lt;
#define POWER_IR  0x2FD00FF // POWER
#define MUTE_IR   0x2FDB04F // MUTE

#include &lt;Wire.h&gt; 
#include &lt;U8glib.h&gt;             // https://github.com/olikraus/u8glib/
#include &lt;Encoder.h&gt;            // http://rcl-radio.ru/wp-content/uploads/2019/05/Encoder.zip    
#include &lt;EEPROM.h&gt;
#include &lt;MsTimer2.h&gt;           // http://rcl-radio.ru/wp-content/uploads/2018/11/MsTimer2.zip       
#include &lt;boarddefs.h&gt;          // входит в состав библиотеки IRremote
#include &lt;IRremote.h&gt;           // http://rcl-radio.ru/wp-content/uploads/2019/06/IRremote.zip
#include &lt;PT2257.h&gt;             // http://rcl-radio.ru/wp-content/uploads/2019/01/PT2257.zip

 U8GLIB_SSD1306_128X32 u8g(U8G_I2C_OPT_NONE);  // I2C / TWI 
 IRrecv irrecv(IR);
 Encoder myEnc(ENC_DT, ENC_CLK);
 decode_results ir; 
 PT2257 rt;

 extern uint8_t SmallFont[],BigNumbers[];
 long times,oldPosition  = -999,newPosition;
 int vol,balans,bass,treb,in,menu;
 bool mute=0,gr1,gr2,w,w1,power=0;

 void setup(){
  Wire.begin();
  irrecv.enableIRIn();
  Serial.begin(9600);
  MsTimer2::set(3, to_Timer);MsTimer2::start();
  if(EEPROM.read(100)!=0){for(int i=0;i&lt;101;i++){EEPROM.update(i,0);}}// очистка памяти при первом включении  
  pinMode(POWER_BUTTON,INPUT_PULLUP);
  pinMode(MUTE_BUTTON,INPUT_PULLUP);
  pinMode(STANDBY_OUT,OUTPUT); 

 u8g.firstPage(); do {
  u8g.setFont(u8g_font_profont29r);u8g.drawStr(5,25,&quot;PT2257&quot;); 
  }while( u8g.nextPage() );

  delay(300);
  digitalWrite(STANDBY_OUT,LOW);
  vol = EEPROM.read(0);balans = EEPROM.read(3)-8;
  audio(); 
 }

 void loop(){
  // IR ////////////////////////////////////////
  if ( irrecv.decode( &amp;ir )) {Serial.print(&quot;0x&quot;);Serial.println( ir.value,HEX);irrecv.resume();times=millis();w=1;}// IR приемник - чтение, в мониторе порта отображаются коды кнопок
  if(ir.value==0){gr1=0;gr2=0;}// запрет нажатий не активных кнопок пульта  
  
 if(power==0){ 
 if(digitalRead(ENC_SW)==LOW || ir.value==MENU){menu++;cl();delay(200);times=millis();w1=1;w=1;if(menu&gt;1){menu=0;}} // меню


 if((digitalRead(MUTE_BUTTON)==LOW || ir.value==MUTE_IR)&amp;&amp; mute==0){mute=1;cl();times=millis();w1=1;w=1;audio();
 u8g.firstPage(); do {u8g.setFont(u8g_font_profont29r);u8g.drawStr(25,25,&quot;MUTE&quot;);}while( u8g.nextPage() );delay(300);menu=100;} // mute on 

 if((digitalRead(MUTE_BUTTON)==LOW || ir.value==MUTE_IR)&amp;&amp; mute==1){mute=0;cl();times=millis();w1=1;w=1;audio();
 delay(300);menu=0;} // mute off 
 }

 if((digitalRead(POWER_BUTTON)==LOW || ir.value==POWER_IR)&amp;&amp; power==0){power=1;cl();times=millis();w1=1;w=1;mute=1;audio();digitalWrite(STANDBY_OUT,HIGH);
 u8g.firstPage(); do {u8g.setFont(u8g_font_profont29r);u8g.drawStr(10,25,&quot;STANDBY&quot;);}while( u8g.nextPage() );delay(2000);menu=100;
 u8g.firstPage(); do {}while( u8g.nextPage() );} // power on 

 if((digitalRead(POWER_BUTTON)==LOW || ir.value==POWER_IR)&amp;&amp; power==1){power=0;cl();times=millis();w1=1;w=1;mute=0;audio();digitalWrite(STANDBY_OUT,LOW);delay(300);menu=0;} // power off 
 
  
//////// VOLUME //////////////////////////////////////////////////////////////////////////////////////////////////////////////  
  if(menu==0){
   if(newPosition != oldPosition){oldPosition = newPosition;if(newPosition&gt;1){newPosition=1;}if(newPosition&lt;-1){newPosition=-1;}
   vol=vol+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;vol_func();audio();}
 
   if(ir.value==UP){vol++;gr1=1;gr2=0;cl();times=millis();w=1;w1=1;vol_func();audio();}// кнопка &gt; 
   if(ir.value==0xFFFFFFFF and gr1==1){vol++;gr2=0;cl();times=millis();w=1;w1=1;vol_func();audio();}// кнопка &gt;&gt;&gt;&gt;&gt;&gt;
   if(ir.value==DW){vol--;gr1=0;gr2=1;cl();times=millis();w=1;w1=1;vol_func();audio();}// кнопка &lt;
   if(ir.value==0xFFFFFFFF and gr2==1){vol--;gr1=0;cl();times=millis();w=1;w1=1;vol_func();audio();}// кнопка &lt;&lt;&lt;&lt;&lt;&lt;
 
  if(w==1){w=0;
 // Serial.println(63-vol+balans);
  u8g.firstPage();  
   do {
  u8g.setFont(u8g_font_profont12r);u8g.drawStr(0,8,&quot;VOLUME&quot;);
  u8g.setFont(u8g_font_profont29r); u8g.setPrintPos(95, 24);u8g.print(vol-8);
  for(int v_pos=0; v_pos&lt;(71-8)*1.3;v_pos+=4){u8g.drawBox(v_pos+0,16, 2, 1);}
  for(int v_pos=0; v_pos&lt;(vol-8)*1.3;v_pos+=4){u8g.drawBox(v_pos+0,18, 2, 9);}
  for(int v_pos=0; v_pos&lt;(71-8)*1.3;v_pos+=4){u8g.drawBox(v_pos+0,28, 2, 1);}
   } while( u8g.nextPage() );
  }}

///////// BALL /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  if(menu==1){
   if(newPosition != oldPosition){oldPosition = newPosition;if(newPosition&gt;1){newPosition=1;}if(newPosition&lt;-1){newPosition=-1;}
   balans=balans+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;ball_func();audio();}

   if(ir.value==UP){balans++;gr1=1;gr2=0;ir.value=0;times=millis();w=1;w1=1;ball_func();audio();}// кнопка &gt; 
   if(ir.value==DW){balans--;gr1=0;gr2=1;ir.value=0;times=millis();w=1;w1=1;ball_func();audio();}// кнопка &lt;
 
  if(w==1){w=0;
//  Serial.println(vol+balans);
//  Serial.println(vol-balans);
  u8g.firstPage();  
   do {
  u8g.setFont(u8g_font_profont12r);u8g.drawStr(0,8,&quot;BALANCE&quot;);
  u8g.setFont(u8g_font_profont29r); 
  if(balans&gt;=0){u8g.setPrintPos(112, 24);u8g.print(balans);u8g.drawStr(95,24,&quot;+&quot;);}
  else{u8g.setPrintPos(95, 24);u8g.print(balans);}

  for(int v_pos=0; v_pos&lt;(12-1)*8;v_pos+=4){u8g.drawBox(v_pos+0,16, 2, 1);}
  const int SCREEN_WIDTH = 84; 
  u8g.drawBox(43,18, 1, 9);// 0 dB
  if(balans &gt;= 0){for(int v_pos=0; v_pos&lt;(balans*4);v_pos+=4){u8g.drawBox(v_pos+48,18, 2, 9);}} 
  else{for(int v_pos=SCREEN_WIDTH-48; v_pos&gt;(SCREEN_WIDTH-(abs(balans)*4)-48); v_pos-=4){u8g.drawBox(v_pos,18, 2, 9);}}
  for(int v_pos=0; v_pos&lt;(12-1)*8;v_pos+=4){u8g.drawBox(v_pos+0,28, 2, 1);}
  
   } while( u8g.nextPage() );
  }}
  

////////////// EEPROM /////////////////////////////////////////////////////////////////////  
  if(millis()-times&gt;5000 &amp;&amp; w1==1 &amp;&amp; power==0 &amp;&amp; mute==0){
     EEPROM.update(0,vol);EEPROM.update(3,balans+8);
     menu=0;w1=0;w=1;myEnc.write(0);}
  }

 
void to_Timer(){newPosition = myEnc.read()/4;} 
void audio(){
  rt.setLeft(vol-8+balans); // int 0...79 
  rt.setRight(vol-8-balans);// int 0...79
  rt.setMute(mute);  // int 0...1
}

void vol_func(){if(vol&gt;71){vol=71;}if(vol&lt;=8){vol=8;}} // int 0 ... int 79 
void ball_func(){if(balans&gt;8){balans=8;}if(balans&lt;=-8){balans=-8;}}
void cl(){ir.value=0;delay(200);} </code></pre></div>]]></description>
			<author><![CDATA[null@example.com (liman324)]]></author>
			<pubDate>Sun, 04 Jan 2026 10:48:27 +0000</pubDate>
			<guid>http://forum.rcl-radio.ru/viewtopic.php?id=723&amp;action=new</guid>
		</item>
		<item>
			<title><![CDATA[TDA8425 + OLED 128x32]]></title>
			<link>http://forum.rcl-radio.ru/viewtopic.php?id=722&amp;action=new</link>
			<description><![CDATA[<p><span class="postimg"><img src="http://forum.rcl-radio.ru/uploads/images/2026/01/c07c38d98b7a963a9d69cac0dbf02185.png" alt="http://forum.rcl-radio.ru/uploads/images/2026/01/c07c38d98b7a963a9d69cac0dbf02185.png" /></span> </p><p><span class="postimg"><img src="http://forum.rcl-radio.ru/uploads/images/2026/01/757dc857d69bfd965d9bed974888f543.png" alt="http://forum.rcl-radio.ru/uploads/images/2026/01/757dc857d69bfd965d9bed974888f543.png" /></span> </p><p><span class="postimg"><img src="http://forum.rcl-radio.ru/uploads/images/2026/01/6ccf049697bc477775a1682a1fa4a8d6.png" alt="http://forum.rcl-radio.ru/uploads/images/2026/01/6ccf049697bc477775a1682a1fa4a8d6.png" /></span> </p><p><span class="postimg"><img src="http://forum.rcl-radio.ru/uploads/images/2026/01/03068df51245af85557b796dca902ae7.png" alt="http://forum.rcl-radio.ru/uploads/images/2026/01/03068df51245af85557b796dca902ae7.png" /></span> </p><p><span class="postimg"><img src="http://forum.rcl-radio.ru/uploads/images/2026/01/c437dbd9d40eeed7bc82d5cccd62b1de.png" alt="http://forum.rcl-radio.ru/uploads/images/2026/01/c437dbd9d40eeed7bc82d5cccd62b1de.png" /></span> </p><p><span class="postimg"><img src="http://forum.rcl-radio.ru/uploads/images/2026/01/03a01820a12435ebe527034ba2f5bba8.png" alt="http://forum.rcl-radio.ru/uploads/images/2026/01/03a01820a12435ebe527034ba2f5bba8.png" /></span> </p><p><span class="postimg"><img src="http://forum.rcl-radio.ru/uploads/images/2026/01/05baa7de0dbc8d9959bc680a09cd0e0c.png" alt="http://forum.rcl-radio.ru/uploads/images/2026/01/05baa7de0dbc8d9959bc680a09cd0e0c.png" /></span> </p><p><span class="postimg"><img src="http://forum.rcl-radio.ru/uploads/images/2026/01/5ef886e5e5edba7e4f293b912e0bfca1.png" alt="http://forum.rcl-radio.ru/uploads/images/2026/01/5ef886e5e5edba7e4f293b912e0bfca1.png" /></span> </p><p><span class="postimg"><img src="http://forum.rcl-radio.ru/uploads/images/2026/01/00c9efff332ec89a1e12b724bea5340d.png" alt="http://forum.rcl-radio.ru/uploads/images/2026/01/00c9efff332ec89a1e12b724bea5340d.png" /></span> </p><p><span class="postimg"><img src="http://forum.rcl-radio.ru/uploads/images/2026/01/7d1dc5c895bf287654b6afdcea1a13ea.png" alt="http://forum.rcl-radio.ru/uploads/images/2026/01/7d1dc5c895bf287654b6afdcea1a13ea.png" /></span> </p><br /><div class="codebox"><pre><code>// энкодер
#define ENC_DT       9
#define ENC_CLK      8
#define ENC_SW       10

// ИК датчик
#define IR           12

// кнопки управления
#define IN_BUTTON       2
#define POWER_BUTTON    3
#define MUTE_BUTTON     4

// выход управления standby
#define STANDBY_OUT     13

// коды кнопок ИК пульта
#define MENU      0x2FDB24D // button encoder
#define UP        0x2FDD02F // &gt;&gt;&gt;
#define DW        0x2FD32CD // &lt;&lt;&lt;
#define INPUT_IR  0x2FD6A95 // IN
#define POWER_IR  0x2FD00FF // POWER
#define MUTE_IR   0x2FDB04F // MUTE

#include &lt;Wire.h&gt; 
#include &lt;U8glib.h&gt;             // https://github.com/olikraus/u8glib/
#include &lt;Encoder.h&gt;            // http://rcl-radio.ru/wp-content/uploads/2019/05/Encoder.zip    
#include &lt;EEPROM.h&gt;
#include &lt;MsTimer2.h&gt;           // http://rcl-radio.ru/wp-content/uploads/2018/11/MsTimer2.zip       
#include &lt;boarddefs.h&gt;          // входит в состав библиотеки IRremote
#include &lt;IRremote.h&gt;           // http://rcl-radio.ru/wp-content/uploads/2019/06/IRremote.zip
#include &lt;TDA8425.h&gt;            // http://rcl-radio.ru/wp-content/uploads/2018/11/TDA8425.zip

 U8GLIB_SSD1306_128X32 u8g(U8G_I2C_OPT_NONE);  // I2C / TWI 
 IRrecv irrecv(IR);
 Encoder myEnc(ENC_DT, ENC_CLK);
 decode_results ir; 
 TDA8425 tda;

 extern uint8_t SmallFont[],BigNumbers[];
 long times,oldPosition  = -999,newPosition;
 int vol,balans,bass,treb,in,menu;
 bool mute=0,gr1,gr2,w,w1,power=0;

 void setup(){
  Wire.begin();
  irrecv.enableIRIn();
  Serial.begin(9600);
  MsTimer2::set(3, to_Timer);MsTimer2::start();
  if(EEPROM.read(100)!=0){for(int i=0;i&lt;101;i++){EEPROM.update(i,0);}}// очистка памяти при первом включении  
  pinMode(IN_BUTTON,INPUT_PULLUP);
  pinMode(POWER_BUTTON,INPUT_PULLUP);
  pinMode(MUTE_BUTTON,INPUT_PULLUP);
  pinMode(STANDBY_OUT,OUTPUT); 

 u8g.firstPage(); do {
  u8g.setFont(u8g_font_profont29r);u8g.drawStr(5,25,&quot;TDA8425&quot;); 
  }while( u8g.nextPage() );

  delay(300);
  digitalWrite(STANDBY_OUT,LOW);
  vol = EEPROM.read(0);bass = EEPROM.read(1);treb = EEPROM.read(2);balans = EEPROM.read(3)-4;in = EEPROM.read(4);
  audio(); 
 }

 void loop(){
  // IR ////////////////////////////////////////
  if ( irrecv.decode( &amp;ir )) {Serial.print(&quot;0x&quot;);Serial.println( ir.value,HEX);irrecv.resume();times=millis();w=1;}// IR приемник - чтение, в мониторе порта отображаются коды кнопок
  if(ir.value==0){gr1=0;gr2=0;}// запрет нажатий не активных кнопок пульта  
  
 if(power==0){ 
 if(digitalRead(ENC_SW)==LOW || ir.value==MENU){menu++;cl();delay(200);times=millis();w1=1;w=1;if(menu&gt;3){menu=0;}} // меню

 if((digitalRead(IN_BUTTON)==LOW || ir.value==INPUT_IR) &amp;&amp; mute==0){in++;cl();times=millis();w1=1;w=1;if(in&gt;1){in=0;}audio();
 u8g.firstPage(); do {u8g.setFont(u8g_font_profont29r);u8g.drawStr(0,25,&quot;INPUT&quot;);u8g.setPrintPos(95, 25);u8g.print(in+1);}while( u8g.nextPage() );delay(1000);} // input 

 if((digitalRead(MUTE_BUTTON)==LOW || ir.value==MUTE_IR)&amp;&amp; mute==0){mute=1;cl();times=millis();w1=1;w=1;audio();
 u8g.firstPage(); do {u8g.setFont(u8g_font_profont29r);u8g.drawStr(25,25,&quot;MUTE&quot;);}while( u8g.nextPage() );delay(300);menu=100;} // mute on 

 if((digitalRead(MUTE_BUTTON)==LOW || ir.value==MUTE_IR)&amp;&amp; mute==1){mute=0;cl();times=millis();w1=1;w=1;audio();
 delay(300);menu=0;} // mute off 
 }

 if((digitalRead(POWER_BUTTON)==LOW || ir.value==POWER_IR)&amp;&amp; power==0){power=1;cl();times=millis();w1=1;w=1;mute=1;audio();digitalWrite(STANDBY_OUT,HIGH);
 u8g.firstPage(); do {u8g.setFont(u8g_font_profont29r);u8g.drawStr(10,25,&quot;STANDBY&quot;);}while( u8g.nextPage() );delay(2000);menu=100;
 u8g.firstPage(); do {}while( u8g.nextPage() );} // power on 

 if((digitalRead(POWER_BUTTON)==LOW || ir.value==POWER_IR)&amp;&amp; power==1){power=0;cl();times=millis();w1=1;w=1;mute=0;audio();digitalWrite(STANDBY_OUT,LOW);delay(300);menu=0;} // power off 
 
  
//////// VOLUME //////////////////////////////////////////////////////////////////////////////////////////////////////////////  
  if(menu==0){
   if(newPosition != oldPosition){oldPosition = newPosition;if(newPosition&gt;1){newPosition=1;}if(newPosition&lt;-1){newPosition=-1;}
   vol=vol+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;vol_func();audio();}
 
   if(ir.value==UP){vol++;gr1=1;gr2=0;cl();times=millis();w=1;w1=1;vol_func();audio();}// кнопка &gt; 
   if(ir.value==0xFFFFFFFF and gr1==1){vol++;gr2=0;cl();times=millis();w=1;w1=1;vol_func();audio();}// кнопка &gt;&gt;&gt;&gt;&gt;&gt;
   if(ir.value==DW){vol--;gr1=0;gr2=1;cl();times=millis();w=1;w1=1;vol_func();audio();}// кнопка &lt;
   if(ir.value==0xFFFFFFFF and gr2==1){vol--;gr1=0;cl();times=millis();w=1;w1=1;vol_func();audio();}// кнопка &lt;&lt;&lt;&lt;&lt;&lt;
 
  if(w==1){w=0;
 // Serial.println(63-vol+balans);
  u8g.firstPage();  
   do {
  u8g.setFont(u8g_font_profont12r);u8g.drawStr(0,8,&quot;VOLUME&quot;);
  u8g.setFont(u8g_font_profont29r); u8g.setPrintPos(95, 24);u8g.print(vol-4);
  for(int v_pos=0; v_pos&lt;(59-3)*1.5;v_pos+=4){u8g.drawBox(v_pos+0,16, 2, 1);}
  for(int v_pos=0; v_pos&lt;(vol-3)*1.5;v_pos+=4){u8g.drawBox(v_pos+0,18, 2, 9);}
  for(int v_pos=0; v_pos&lt;(59-3)*1.5;v_pos+=4){u8g.drawBox(v_pos+0,28, 2, 1);}
   } while( u8g.nextPage() );
  }}

///////// BASS /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  if(menu==1){
   if(newPosition != oldPosition){oldPosition = newPosition;if(newPosition&gt;1){newPosition=1;}if(newPosition&lt;-1){newPosition=-1;}
   bass=bass+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;bass_func();audio();}

   if(ir.value==UP){bass++;gr1=1;gr2=0;ir.value=0;times=millis();w=1;w1=1;bass_func();audio();}// кнопка &gt; 
   if(ir.value==DW){bass--;gr1=0;gr2=1;ir.value=0;times=millis();w=1;w1=1;bass_func();audio();}// кнопка &lt;
 
  if(w==1){w=0;

  u8g.firstPage();  
   do {
  u8g.setFont(u8g_font_profont12r);u8g.drawStr(0,8,&quot;BASS&quot;);
  u8g.setFont(u8g_font_profont29r); u8g.setPrintPos(95, 24);u8g.print(bass-6);
  for(int v_pos=0; v_pos&lt;(11-1)*8;v_pos+=4){u8g.drawBox(v_pos+0,16, 2, 1);}
  for(int v_pos=0; v_pos&lt;(bass-1)*8;v_pos+=4){u8g.drawBox(v_pos+0,18, 2, 9);}
  for(int v_pos=0; v_pos&lt;(11-1)*8;v_pos+=4){u8g.drawBox(v_pos+0,28, 2, 1);}
   } while( u8g.nextPage() );
  }}

///////// TREB /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  if(menu==2){
   if(newPosition != oldPosition){oldPosition = newPosition;if(newPosition&gt;1){newPosition=1;}if(newPosition&lt;-1){newPosition=-1;}
   treb=treb+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;treb_func();audio();}

   if(ir.value==UP){treb++;gr1=1;gr2=0;ir.value=0;times=millis();w=1;w1=1;treb_func();audio();}// кнопка &gt; 
   if(ir.value==DW){treb--;gr1=0;gr2=1;ir.value=0;times=millis();w=1;w1=1;treb_func();audio();}// кнопка &lt;
 
  if(w==1){w=0;

  u8g.firstPage();  
   do {
  u8g.setFont(u8g_font_profont12r);u8g.drawStr(0,8,&quot;TREBLE&quot;);
  u8g.setFont(u8g_font_profont29r); u8g.setPrintPos(95, 24);u8g.print(treb-6);
  for(int v_pos=0; v_pos&lt;(10-1)*8;v_pos+=4){u8g.drawBox(v_pos+0,16, 2, 1);}
  for(int v_pos=0; v_pos&lt;(treb-1)*8;v_pos+=4){u8g.drawBox(v_pos+0,18, 2, 9);}
  for(int v_pos=0; v_pos&lt;(10-1)*8;v_pos+=4){u8g.drawBox(v_pos+0,28, 2, 1);}
   } while( u8g.nextPage() );
  }}

///////// BALL /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  if(menu==3){
   if(newPosition != oldPosition){oldPosition = newPosition;if(newPosition&gt;1){newPosition=1;}if(newPosition&lt;-1){newPosition=-1;}
   balans=balans+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;ball_func();audio();}

   if(ir.value==UP){balans++;gr1=1;gr2=0;ir.value=0;times=millis();w=1;w1=1;ball_func();audio();}// кнопка &gt; 
   if(ir.value==DW){balans--;gr1=0;gr2=1;ir.value=0;times=millis();w=1;w1=1;ball_func();audio();}// кнопка &lt;
 
  if(w==1){w=0;
 // Serial.println(63-vol+balans);
 // Serial.println(63-vol-balans);
  u8g.firstPage();  
   do {
  u8g.setFont(u8g_font_profont12r);u8g.drawStr(0,8,&quot;BALANCE&quot;);
  u8g.setFont(u8g_font_profont29r); 
  if(balans&gt;=0){u8g.setPrintPos(112, 24);u8g.print(balans);u8g.drawStr(95,24,&quot;+&quot;);}
  else{u8g.setPrintPos(95, 24);u8g.print(balans);}

  for(int v_pos=0; v_pos&lt;(12-1)*8;v_pos+=4){u8g.drawBox(v_pos+0,16, 2, 1);}
  const int SCREEN_WIDTH = 84; 
  u8g.drawBox(43,18, 1, 9);// 0 dB
  if(balans &gt;= 0){for(int v_pos=0; v_pos&lt;(balans*8);v_pos+=4){u8g.drawBox(v_pos+48,18, 2, 9);}} 
  else{for(int v_pos=SCREEN_WIDTH-48; v_pos&gt;(SCREEN_WIDTH-(abs(balans)*8)-48); v_pos-=4){u8g.drawBox(v_pos,18, 2, 9);}}
  for(int v_pos=0; v_pos&lt;(12-1)*8;v_pos+=4){u8g.drawBox(v_pos+0,28, 2, 1);}
  
   } while( u8g.nextPage() );
  }}
  

////////////// EEPROM /////////////////////////////////////////////////////////////////////  
  if(millis()-times&gt;5000 &amp;&amp; w1==1 &amp;&amp; power==0 &amp;&amp; mute==0){
     EEPROM.update(0,vol);EEPROM.update(1,bass);EEPROM.update(2,treb);EEPROM.update(3,balans+4);EEPROM.update(4,in);
     menu=0;w1=0;w=1;myEnc.write(0);}
  }


  
void to_Timer(){newPosition = myEnc.read()/4;} 
void audio(){
  tda.setVolumeL(vol+balans);
  tda.setVolumeR(vol-balans);
  tda.setBass(bass);
  tda.setTreble(treb);
  tda.setMute(mute);
  tda.setSource(in);
 } 

void vol_func(){if(vol&gt;59){vol=59;}if(vol&lt;=4){vol=4;}} // int 0 = min ... int 63 = max + ballans 4 dB 
void bass_func(){if(bass&gt;11){bass=11;}if(bass&lt;2){bass=2;}} // int 6 = 0 dB | int 2 = -12 dB | int 11 = 15 dB
void treb_func(){if(treb&gt;10){treb=10;}if(treb&lt;2){treb=2;}} // int 6 = 0 dB | int 2 = -12 dB | int 10 = 12 dB
void ball_func(){if(balans&gt;4){balans=4;}if(balans&lt;=-4){balans=-4;}}
void cl(){ir.value=0;delay(200);} </code></pre></div>]]></description>
			<author><![CDATA[null@example.com (liman324)]]></author>
			<pubDate>Sun, 04 Jan 2026 06:40:52 +0000</pubDate>
			<guid>http://forum.rcl-radio.ru/viewtopic.php?id=722&amp;action=new</guid>
		</item>
		<item>
			<title><![CDATA[Терморегулятор на сдвиговых регистрах 74НС595]]></title>
			<link>http://forum.rcl-radio.ru/viewtopic.php?id=721&amp;action=new</link>
			<description><![CDATA[<p>На сайте <a href="http://rcl-radio.ru/?p=53543">http://rcl-radio.ru/?p=53543</a>&nbsp; &nbsp; прочитал ,там 74НС595,&nbsp; &nbsp;но&nbsp; у меня&nbsp; есть индикатор TM1637, вохиожна ли переделка. Есть&nbsp; на сайте схема&nbsp; на TM1637, но с энкодером, а мне нужна на кнопках. Пробывал фркенштеить программу, но ума и опыта&nbsp; не хватает. Если уважаемый&nbsp; автор&nbsp; &nbsp;liman28 сможет&nbsp; поправить&nbsp; прогу , то буду признателен.</p>]]></description>
			<author><![CDATA[null@example.com (Сергей из Сибири)]]></author>
			<pubDate>Thu, 01 Jan 2026 13:54:24 +0000</pubDate>
			<guid>http://forum.rcl-radio.ru/viewtopic.php?id=721&amp;action=new</guid>
		</item>
		<item>
			<title><![CDATA[Измеритель СО2 с управлением вытяжкой]]></title>
			<link>http://forum.rcl-radio.ru/viewtopic.php?id=708&amp;action=new</link>
			<description><![CDATA[<p>Нашел я проект <a href="http://%20http://radiopench.blog96.fc2.com/blog-entry-1101.html?sp"> http://radiopench.blog96.fc2.com/blog- … 01.html?sp</a> .<br />Весьма продуманная конструкция.<br />Перевел комментарии.</p><p>Решил расширить функционал - добавить управление вытяжкой (конечно в идеале ШИМ, но это я не потяну).<br />Добавил.</p><p>Потом решил добавить возможность принудительного включения кнопкой на 30 минут (в авто режиме включается при уровне 900, выключается при уровне 799).<br />Вот тут и начались проблемы - если уровень СО2 ниже 799 то не включается.<br />Сейчас в скетче время установлено 1 минута.</p><p>Все строки, которые я добавил в оригинальный скетч я в комментариях добавил знак &quot;+++++&quot;. Это что б проще найти мои художества.<br />Хэлп ми - как сделать что б кнопкой можно было включить вне зависимости от того какой уровень СО2.</p><div class="codebox"><pre><code>#include &lt;Wire.h&gt;              // Библиотека для работы с I2C
#include &lt;Adafruit_GFX.h&gt;      // Библиотека для работы с графикой
#include &lt;Adafruit_SSD1306.h&gt;  // Библиотека для работы с OLED-дисплеем (0.96 дюйма)
#include &lt;SoftwareSerial.h&gt;    // Библиотека для использования программного последовательного порта
#include &lt;MsTimer2.h&gt;          // Библиотека для работы с таймерами
#include &lt;EEPROM.h&gt;            // Библиотека для работы с EEPROM

// Определение пинов
#define MODE_PIN    2
#define ENTER_PIN   3
#define SELECT_PIN  4
#define onPin      6             // Кнопка ручного включения вентилятора++++++++++
#define RX_PIN     10
#define TX_PIN     11
#define LED_PIN    7             // Выход индикатора измерения
#define funPin     5             // Выход управления вентилятором+++++
#define BAUDRATE           9600  // Скорость передачи данных для MH-Z19 (фиксированная)
#define T1                 1000  // Интервал измерений в миллисекундах (минимум 1000 = 1 секунда))
#define DISP_ON_TIME       30000  // Время включения дисплея (время до отключения)
#define DISP_WAKEUP_VALUE  1000  // Уровень CO2, при котором дисплей включается
#define FUN_VALUE_ON        900  // Уровень CO2, при котором вентилятор ВКЛ+++++++++
#define FUN_VALUE_OFF       799  // Уровень CO2, при котором вентилятор ВКЛ++++++++
#define SCREEN_WIDTH 128         // Ширина OLED-дисплея
#define SCREEN_HEIGHT 64         // Высота OLED-дисплея
#define OLED_RESET    -1         // Пин сброса (или -1, если используется общий сброс Arduino)

// Инициализация OLED-дисплея
Adafruit_SSD1306 OLED(SCREEN_WIDTH, SCREEN_HEIGHT, &amp;Wire, OLED_RESET);


// Объявление переменных
unsigned int co2Val;             // Измеренное значение CO2
unsigned int calib;              // Режим калибровки
int dispTimer = DISP_ON_TIME;    // Оставшееся время до выключения дисплея

// Для управления кнопкой
bool funState = false;       // Состояние вентилятора+++++++
unsigned long funOnTime = 0; // Время включения вентилятора+++++++++

byte ReadCO2[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79}; // Команда чтения CO2
byte SCalOn[9]  = {0xFF, 0x01, 0x79, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xE6}; // Команда включения калибровки
byte SCalOff[9] = {0xFF, 0x01, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86}; // Команда выключения калибровки
byte RetVal[9];                                                           // Массив для ответа от датчика


// Структура для описания диапазона графиков
struct recipe {     
  int gInterval;   // Интервал графика
  byte scaleV;     // Время на один делитель (30 пикселей)
  char scaleC[2];  // Единицы времени
};

struct recipe hRange[12] = {
  {   1, 30, &quot;s&quot;},  // Диапазон 0: период графика, время на делитель, единицы времени
  {   2,  1, &quot;m&quot;},  //       1
  {   4,  2, &quot;m&quot;},  //       2
  {  10,  5, &quot;m&quot;},  //       3
  {  20, 10, &quot;m&quot;},  //       4
  {  40, 20, &quot;m&quot;},  //       5
  { 120,  1, &quot;h&quot;},  //       6
  { 240,  2, &quot;h&quot;},  //       7
  { 480,  4, &quot;h&quot;},  //       8
  { 960,  8, &quot;h&quot;},  //       9
  {1440, 12, &quot;h&quot;},  //      10
  {2880,  1, &quot;d&quot;},  //      11
};

int dataBuff[91]; // Буфер данных (91 элемент от 0 до 90)
int latestData; // Последние данные CO2
int dataMin = 400; // Минимальное значение для отображения графика
int dataMax = 400; // Максимальное значение для отображения графика
int tCount = 0; // Счетчик времени интервала логирования
unsigned int rNum = 0; // Номер диапазона (rangeNumber) от 0 до 11
char chrBuff[6]; // Буфер символов для строковых данных

volatile boolean timerFlag = false; // Флаг прерывания таймера
boolean entPushed = false; // Флаг нажатия кнопки ENTER

// Инициализация программного последовательного порта для взаимодействия с MH-Z19C
SoftwareSerial mySerial(RX_PIN, TX_PIN);  // MH-Z19C

void setup() {
    pinMode(MODE_PIN, INPUT_PULLUP); // Установка режима авто-калибровки
    pinMode(ENTER_PIN, INPUT_PULLUP); // Установка кнопки ENTER как входа с подтяжкой
    pinMode(SELECT_PIN, INPUT_PULLUP); // Установка кнопки SELECT как входа с подтяжкой
    pinMode(LED_PIN, OUTPUT); // Установка пина LED как выхода
    pinMode(RX_PIN, INPUT); // Установка пина RX как входа для программного порта
    pinMode(TX_PIN, OUTPUT); // Установка пина TX как выхода для программного порта
    pinMode(onPin, INPUT_PULLUP); // Настройка кнопки включения вентиляторв с подтяжкой+++++++
    pinMode(funPin, OUTPUT);           // Настройка пина вентилятора как выход++++++++++
    mySerial.begin(9600); // Инициализация программного последовательного порта с заданной скоростью


  for (int i = 0; i &lt;= 90; i++) {
    dataBuff[i] = -1;                 // Заполнение буфера данных значением -1 (неопределено)
  }

  if (!OLED.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32
    for (;;);                                    // Остановка программы в случае неудачи инициализации OLED-дисплея
  }
  OLED.clearDisplay();                 // Очистка дисплея перед выводом информации
  OLED.setTextColor(WHITE);            // Установка цвета текста на белый
  if (digitalRead(ENTER_PIN) == LOW) {  
    rangeSet();                        // Если кнопка ENTER нажата при запуске - выполнить настройку диапазона
  }
  rNum = EEPROM.read(0);               // Чтение номера диапазона из EEPROM

  OLED.setCursor(10, 12);
  OLED.print(F(&quot;CO2 monitor V0.8&quot;));   // // Вывод стартового сообщения на дисплей
  OLED.display();

  if (digitalRead(MODE_PIN) == LOW) {  
    calib = 0;                         // Если режим LOW - установить ручную калибровку (без авто-калибровки)
  } else {                             
    calib = 1;                         // В противном случае установить авто-калибровку (по умолчанию)
  }
  setCalMode(calib);                   // Установка режима калибровки: 0 - ручной, 1 - автоматический
  measure();                           // Первичное измерение CO2
  MsTimer2::set(T1, timer2_IRQ);       // Запуск таймера
  MsTimer2::start();
}

void loop() {

// Проверяем состояние кнопки (активная низкая)+++++++++++
  if (digitalRead(onPin) == LOW &amp;&amp; !funState) {
    funState = true;               // Включаем светодиод
    digitalWrite(funPin, HIGH);    // Включаем светодиод
    funOnTime = millis();          // Запоминаем время включения
  }
  
  // Проверяем, прошло ли 30 минут (1800000 миллисекунд)
  if (funState &amp;&amp; (millis() - funOnTime &gt;= 30000)) {
    funState = false;              // Выключаем светодиод
    digitalWrite(funPin, LOW);     // Выключаем светодиод
  }
  
  while (timerFlag != true) {              
    if (digitalRead(ENTER_PIN) == LOW) {   
      entPushed = true;                   // Установка флага нажатия кнопки ENTER в true при нажатии кнопки во время ожидания
    }
  }
  timerFlag = false;                      // Сброс флага таймера для следующего прерывания

  if (entPushed == true) {                 
    if (dispTimer &gt; 1) {                   
      dispTimer = 1;                      // Если дисплей еще включен - выключить его
    } else {                              
      dispTimer = DISP_ON_TIME;           // Если дисплей выключен - вернуть его в исходное состояние (включить)
    }
  }
  entPushed = false;                      // Сброс флага нажатия кнопки ENTER

  digitalWrite(LED_PIN, HIGH);
  measure();                              // Включение светодиода во время измерения CO2
  digitalWrite(LED_PIN, LOW);
  latestData = co2Val;                    // Сохранение последнего измеренного значения CO2
  if (co2Val &gt; DISP_WAKEUP_VALUE) {        
    dispTimer = DISP_ON_TIME;             // Если уровень CO2 превышает заданное значение - сбросить таймер дисплея
  }
  if (co2Val &gt; FUN_VALUE_ON){
    digitalWrite(funPin, HIGH);          // Включить вентилятор если CO2 больше +++++++++++++
    }          
  if (co2Val &lt; FUN_VALUE_OFF){            // Если значение CO2 меньше вентилятор ВЫКЛ++++++++++++++!!!!!!!!!!!!!!!!!!!!!!!
    digitalWrite(funPin, LOW);
  }

  tCount++;                               // Увеличение счетчика интервалов логирования
  if (tCount == hRange[rNum].gInterval) { // Если достигнут заданный интервал логирования - сохранить данные в буфер
    saveBuff();                           // Сброс счетчика интервалов логирования
    tCount = 0;
  }

  dispTimer--; // Декрементирование таймера отображения
    if (dispTimer &gt; 0) { 
        disp(); // Если таймер больше нуля - отобразить данные на OLED-дисплее
    } else {
        OLED.clearDisplay(); // Если таймер равен нулю - очистить OLED-дисплей (выключить его)
        OLED.display(); 
        dispTimer = 1; // Установить значение для следующего отключения дисплея
    }
}

// Чтение значения концентрации CO2 с MH-Z19C

int measure() {                                 // MH-Z19С
  int err;
  mySerial.write(ReadCO2, sizeof ReadCO2);      // Отправка команды измерения
  memset(RetVal, 0x00, sizeof RetVal);          // Очистка буфера приема
  mySerial.readBytes((char *)RetVal, sizeof RetVal); // Получение результатов измерения

  if (RetVal[0] == 0xff &amp;&amp; RetVal[1] == 0x86) { // Если чтение прошло успешно
    co2Val = RetVal[2] * 256 + RetVal[3];       // Вычисление концентрации CO2
    err = 0;
  } else {
    co2Val = 399;                               // Если чтение неудачно, вернуть это значение
    err = 1;
  }
  return err;
}

void setCalMode(int m) {                     // Установка режима калибровки
  if (m == 0) {
    mySerial.write(SCalOff, sizeof SCalOff); // Выключение калибровки 
  }
  if (m == 1) {
    mySerial.write(SCalOn, sizeof SCalOn);   // Включение калибровки 
  }
  mySerial.readBytes((char *)RetVal, sizeof RetVal); // Дамми-прием. Без этого не получится прочитать результаты измерений после включения питания
  delay(100);
}

void saveBuff() {                       // Обновление буфера данных и определение максимального и минимального значений
  int d;
  dataMin = 9999;                       // Минимальное значение
  dataMax = 0;                          // Максимальное значение
  for (int i = 90; i &gt;= 1; i--) {       // Сохранение значений в массиве и определение максимального и минимального значений
    d = dataBuff[i - 1];                // Предыдущее значение
    dataBuff[i] = d;                    // Сдвиг массива
    if (d != -1) {                      // Если сдвинутые данные являются допустимыми значениями
      if (d &lt; dataMin) {                // обновить минимальное значение
        dataMin = d;
      }
      if (d &gt; dataMax) {                // обновить максимальное значение
        dataMax = d;
      }
    }
  }
  dataBuff[0] = latestData; // Запись последних данных в начало массива
    if (latestData &lt; dataMin) { // Если последние данные меньше минимального значения
        dataMin = latestData; 
    } 
    if (latestData &gt; dataMax) { // Если последние данные больше максимального значения
        dataMax = latestData; 
    } 
    if (dataMin &lt; 0) { 
        dataMin = 0; // Но нижний предел - 0 
    } 
    if (dataMax &gt; 5000) { 
        dataMax = 5000; // Но если больше 5000, ограничить до 5000 
    } 
}


void disp() { // Отображение на OLED-экране
    OLED.clearDisplay(); // Очистка экрана
    headWrite(); // Запись заголовка
    graphWrite(); // Отображение фона графика
    graphPlot(); // Отображение графика в виде линий
    OLED.display(); // Передача данных и отображение на экране
}

void headWrite() { // Отображение заголовка
    OLED.setCursor(0, 0); 
    OLED.setTextSize(1); // Маленький шрифт для первой строки
    OLED.print(F(&quot;CO2&quot;)); 
    OLED.setCursor(16 * 6, 0); // Отображение режима калибровки в правом верхнем углу
    if (calib == 0) { 
        OLED.print(F(&quot;AZoff&quot;)); 
    } else { 
        OLED.print(F(&quot;AZon&quot;)); 
    } 
    OLED.setCursor(24, 0); 
    OLED.setTextSize(2); // Увеличенный шрифт для значения CO2
    sprintf(chrBuff, &quot;%4d&quot;, co2Val); // Форматирование значения CO2 в 4 цифры
    OLED.print(chrBuff); // Отображение значения CO2
    OLED.setCursor(26 + 4 * 6 * 2, 7); // Перемещение курсора для отображения единицы измерения
    OLED.setTextSize(1); 
    OLED.print(F(&quot;ppm&quot;)); // Отображение единицы измерения
    OLED.print(&quot; &quot;); 
    sprintf(chrBuff, &quot;%4d&quot;, (hRange[rNum].gInterval - tCount) - 1); // Остаток времени до обновления графика
    OLED.setCursor(102, 8); 
    OLED.print(chrBuff); 
}


void graphWrite() {                       // Рисование фона графика
  OLED.drawFastVLine(30, 16, 40, WHITE);  // Левый ориентир (вертикальная линия)
  for (int x = 30; x &lt;= 120; x += 4) {
    OLED.drawFastHLine(x, 36, 2, WHITE);  // Рисование пунктирной линии по центру (горизонтальная пунктирная линия)
  }

  for (int x = (120 - 30); x &gt; 40; x -= 30) {
    for (int y = 16; y &lt; 55; y += 4) {
      OLED.drawFastVLine(x, y, 2, WHITE); // Рисование двух пунктирных вертикальных линий
    }
  }
  // Левая шкала (отображение концентрации)
    OLED.drawFastHLine(26, 16, 4, WHITE); // Метка максимального значения
    OLED.drawFastHLine(26, 36, 4, WHITE); // Центр
    OLED.drawFastHLine(26, 55, 4, WHITE); // Минимум
    OLED.setCursor(0, 16); // Отображение максимального значения
    sprintf(chrBuff, &quot;%4d&quot;, dataMax); 
    OLED.print(chrBuff); 
    OLED.setCursor(0, 32); // Отображение центрального значения
    sprintf(chrBuff, &quot;%4d&quot;, (dataMax + dataMin) / 2); 
    OLED.print(chrBuff); 
    OLED.setCursor(0, 48); // Отображение минимального значения
    sprintf(chrBuff, &quot;%4d&quot;, dataMin); 
    OLED.print(chrBuff); 

  // Нижняя шкала (отображение времени)
    OLED.setCursor(19, 57); // Левая шкала времени
    sprintf(chrBuff, &quot;%+3d&quot;, (hRange[rNum].scaleV) * -3); // Получение значения из структуры и умножение на -3
    OLED.print(chrBuff); // Передача на OLED
    OLED.print(hRange[rNum].scaleC); // Отображение единицы измерения    
    OLED.setCursor(49, 57); // Центральная шкала времени
    sprintf(chrBuff, &quot;%+3d&quot;, (hRange[rNum].scaleV) * -2); // Умножение на -2
    OLED.print(chrBuff); 
    OLED.print(hRange[rNum].scaleC);    
    OLED.setCursor(79, 57); // Правая шкала времени
    sprintf(chrBuff, &quot;%+3d&quot;, (hRange[rNum].scaleV) * -1); // Умножение на -1
    OLED.print(chrBuff); 
    OLED.print(hRange[rNum].scaleC);    
    OLED.setCursor(118, 57); // Ноль времени
    OLED.print(F(&quot;0&quot;)); 
}

void graphPlot() { // Отображение данных в виде линейного графика на основе значений массива
    long y1, y2; 
    for (int i = 0; i &lt;= 89; i++) { 
        if (dataBuff[i + 1] == -1) { // Если данные y2 неопределены (-1), прервать цикл
            break; // Прекращение построения графика
        } 
        y1 = map(dataBuff[i], dataMin, dataMax, 55, 16); // Преобразование для координат графика
        y2 = map(dataBuff[i + 1], dataMin, dataMax, 55, 16); // Преобразование для координат графика
        OLED.drawLine(120 - i, y1, 119 - i, y2, WHITE); // Рисование графика концентрации CO2 линией
    } 
}


void rangeSet() {                              // Установка диапазона записи данных
  unsigned int d;
  d = EEPROM.read(0);
  if (d &gt; 11) {                                // Если номер диапазона вне диапазона,
    d = 0;                                     // установить в 0
  }
  OLED.setCursor(0, 40);                       // Сначала записать маленькие буквы
  OLED.print(F(&quot;SEL:change value&quot;));
  OLED.setCursor(0, 50);
  OLED.print(F(&quot;ENT:save and exit&quot;));
  OLED.setCursor(0, 0);
  OLED.setTextSize(2);                         // Следующие строки будут отображены шрифтом в 2 раза больше
  OLED.print(F(&quot;Range set&quot;));
  OLED.display();
  while (digitalRead(ENTER_PIN) == LOW) {      // Ждать, пока кнопка ENTER не будет отпущена
  }
  delay(30);
  OLED.setCursor(0, 20);
  OLED.print(F(&quot;Fs = &quot;));                      // Полный масштаб =
  sprintf(chrBuff, &quot;%2d&quot;, 3 * (hRange[d].scaleV)); // Получить значение из определения диапазона и умножить на 3
  OLED.print(chrBuff);                         // Передать на OLED
  OLED.print(hRange[d].scaleC);                // Отображение единицы измерения
  OLED.display();                              // Фактическое отображение
  while (digitalRead(ENTER_PIN) == HIGH) {     // Ждать, пока кнопка ENTER не будет нажата
    if (digitalRead(SELECT_PIN) == LOW) {
      d++;                                     // Увеличить номер диапазона
      if (d &gt; 11) {                            // Если номер диапазона превышает верхний предел
        d = 0;                                 // Вернуться к началу
      }
      OLED.fillRect(0, 20, 128, 16, BLACK);    // Закрасить предыдущие значения черным прямоугольником
      OLED.setCursor(0, 20);
      OLED.print(F(&quot;Fs = &quot;));
      sprintf(chrBuff, &quot;%2d&quot;, 3 * (hRange[d].scaleV)); // Получить значение из определения диапазона и умножить на 3
      OLED.print(chrBuff);                     // Передать на OLED
      OLED.print(hRange[d].scaleC);            // Отображение единицы измерения
      OLED.display();
      while (digitalRead(SELECT_PIN) == LOW) { // Ждать, пока кнопка SELECT не будет отпущена
      }
      delay(30);
    }
  }
  EEPROM.write(0, d);                          // Сохранить номер диапазона в EEPROM
  OLED.clearDisplay();
  OLED.setCursor(0, 0);
  OLED.setTextSize(1);                 
  OLED.display();
}

void timer2_IRQ() {                        // Прерывание MsTime
  timerFlag = true;                        // Установить флаг, так как произошло прерывание
}</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (Karl)]]></author>
			<pubDate>Sun, 17 Aug 2025 14:07:48 +0000</pubDate>
			<guid>http://forum.rcl-radio.ru/viewtopic.php?id=708&amp;action=new</guid>
		</item>
		<item>
			<title><![CDATA[pga2311u + oled 0.96]]></title>
			<link>http://forum.rcl-radio.ru/viewtopic.php?id=681&amp;action=new</link>
			<description><![CDATA[<p>Здравствуйте! Для начала хотел бы поблагодарить за такой замечательный ресурс, с вашей помощью собрал несколько отличных проектов(на tda 7439, и bd37534).<br /> Теперь хочу собрать на pga2311, единственное что можно в&nbsp; ваш скетч внести измениия: использовать oled, добавить селектор входов(три пары реле) и управление выходными реле(задержка включения АС)</p>]]></description>
			<author><![CDATA[null@example.com (sushniakk)]]></author>
			<pubDate>Tue, 05 Nov 2024 06:33:09 +0000</pubDate>
			<guid>http://forum.rcl-radio.ru/viewtopic.php?id=681&amp;action=new</guid>
		</item>
		<item>
			<title><![CDATA[Транзистортестер на LGT8F328P ( компиляция)]]></title>
			<link>http://forum.rcl-radio.ru/viewtopic.php?id=678&amp;action=new</link>
			<description><![CDATA[<p>Нашел <a href="https://github.com/DurandA/transistor-tester-lgt328p">https://github.com/DurandA/transistor-tester-lgt328p</a> проект.<br />Учитывая ТТХ LGT8F328P весьма заманчиво.<br />Одно &quot;но&quot; - по имеющимся инструкциям не получается получить *. hex.</p><p>По сему вопрос: Александр, насколько Вам интересно написать инструкцию по компиляции? Или дать ссылку на толковую программу и мануал? </p><p>Ну или помочь скомпилировать проект под SSD 1,3&nbsp; и 0,96&nbsp; дюйма?</p>]]></description>
			<author><![CDATA[null@example.com (Karl2233)]]></author>
			<pubDate>Tue, 22 Oct 2024 15:28:58 +0000</pubDate>
			<guid>http://forum.rcl-radio.ru/viewtopic.php?id=678&amp;action=new</guid>
		</item>
		<item>
			<title><![CDATA[TDA7419+oled+IR на ESP32C3]]></title>
			<link>http://forum.rcl-radio.ru/viewtopic.php?id=676&amp;action=new</link>
			<description><![CDATA[<p>Автору респект за сайт и проделанную работу. Возможна ли перекомпиляция скетча TDA7419+oled+IR на ESP32C3?</p>]]></description>
			<author><![CDATA[null@example.com (sergerz)]]></author>
			<pubDate>Mon, 07 Oct 2024 13:43:44 +0000</pubDate>
			<guid>http://forum.rcl-radio.ru/viewtopic.php?id=676&amp;action=new</guid>
		</item>
		<item>
			<title><![CDATA[Часы на адресной ленте WS2812 (Разработка)]]></title>
			<link>http://forum.rcl-radio.ru/viewtopic.php?id=651&amp;action=new</link>
			<description><![CDATA[<p>Привет всем.<br />Помогите подправить скетч из этой темы.<br /><a href="http://forum.rcl-radio.ru/viewtopic.php?id=432">http://forum.rcl-radio.ru/viewtopic.php?id=432</a></p><p>При включении устанавливается яркость на минимуме.<br />Цвет красный.<br />Что нужно переписать что бы яркость при включении была на максимуме, а цвет зеленый.</p><p>// Atmega328, Atmega8 16MHz</p><p>#include &lt;avr/io.h&gt;<br />#include &lt;util/delay.h&gt;<br />#define ADDR_DS3231&nbsp; &nbsp; 0b1101000<br />#define CPU_F&nbsp; &nbsp;16000000 // Clock Speed <br />#define SCL_F&nbsp; &nbsp;100000 // // I2C Speed<br />#define L_BIT&nbsp; &nbsp; PORTB &amp;= ~(1&lt;&lt;PB0)<br />#define H_BIT&nbsp; &nbsp; PORTB |=&nbsp; (1&lt;&lt;PB0)&nbsp; &nbsp; <br />#define LED_MAX 88</p><p>&nbsp; byte rr[LED_MAX],gg[LED_MAX],bb[LED_MAX],r,g,b;<br />&nbsp; int i,up,down,brig=1,hh,mm;<br />&nbsp; byte sec,min,hour,datat,mont,year,day;<br />&nbsp; byte r_led=0,g_led=1,b_led=0;<br />&nbsp; byte mode;<br />&nbsp; bool sett,w,w1;<br />&nbsp; unsigned long times,times0;</p><p>int main(void){<br />&nbsp; &nbsp; cli();<br />&nbsp; TWBR = (((CPU_F)/(SCL_F)-16 )/2) ;<br />&nbsp; TWSR = 0;<br />&nbsp; DDRD &amp;= ~(1&lt;&lt;PD2);// INPUT SQW DS3231<br />&nbsp; DDRB |= (1&lt;&lt;PB0); // INPUT WS2812B (D8 - ARDUINO)<br />&nbsp; DDRD &amp;= ~(1&lt;&lt;PD3);// INPUT BUTTON MODE<br />&nbsp; DDRD &amp;= ~(1&lt;&lt;PD4);// INPUT BUTTON UP<br />&nbsp; DDRD &amp;= ~(1&lt;&lt;PD5);// INPUT BUTTON DOWN<br />&nbsp; DDRD &amp;= ~(1&lt;&lt;PD6);// INPUT BUTTON SET<br />&nbsp; PORTD |= (1&lt;&lt;PD3);PORTD |= (1&lt;&lt;PD4);PORTD |= (1&lt;&lt;PD5);PORTD |= (1&lt;&lt;PD6);<br />&nbsp; DDRB |= (1&lt;&lt;PB0); // INPUT WS2812B (D8 - ARDUINO)<br />&nbsp; DDRD &amp;= ~(1&lt;&lt;PD2);// BUTTON (D2 - ARDUINO)<br />&nbsp; PORTD |=(1&lt;&lt;PD2); // INPUT_PULLUP<br />&nbsp; /// TIMER 0 = 1ms<br />&nbsp; ADCSRA = 0b10000100; <br />&nbsp; TCCR0A = 0;TCCR0B = 0;TCNT0 = 0;<br />&nbsp; OCR0A = 249;<br />&nbsp; TCCR0A |= (1 &lt;&lt; WGM01);<br />&nbsp; TCCR0B |= (1 &lt;&lt; CS01) | (1 &lt;&lt; CS00);<br />&nbsp; TIMSK0 |= (1 &lt;&lt; OCIE0A);<br />&nbsp; sei();<br />&nbsp; _delay_ms(100);<br />&nbsp; i2c_write(ADDR_DS3231,0x0E,0b00000000);<br />&nbsp; //set_time(21,1,12,26,12,12,0);// год 00-99, ДН 1-7 (1=ВС), месяц 1-12, дата 1-31, час 0-23, минуты 0-59, секунды 0-59<br />&nbsp; if(EEPROM_read(100)!=0){for(int i1=0;i1&lt;101;i1++){EEPROM_write(i1,1);}}// очистка памяти при первом включении&nbsp; &nbsp;<br />&nbsp; mode = EEPROM_read(0);brig = EEPROM_read(1);</p><p>while(1){<br />/////// BUTTON ///////////////////////////////////////////////<br />&nbsp; if(((PIND &gt;&gt; PD3) &amp; 1) == 0){mode++;if(mode&gt;7){mode=0;}_delay_ms(300);w=1;times0=times;}<br />&nbsp; switch(mode){<br />&nbsp; &nbsp; case 0: r_led=1,g_led=1,b_led=1; break;<br />&nbsp; &nbsp; case 1: r_led=1,g_led=0,b_led=0; break;<br />&nbsp; &nbsp; case 2: r_led=0,g_led=1,b_led=0; break;<br />&nbsp; &nbsp; case 3: r_led=0,g_led=0,b_led=1; break;<br />&nbsp; &nbsp; case 4: r_led=1,g_led=1,b_led=0; break;<br />&nbsp; &nbsp; case 5: r_led=1,g_led=0,b_led=1; break;<br />&nbsp; &nbsp; case 6: r_led=0,g_led=1,b_led=1; break;<br />&nbsp; &nbsp; case 7: r_led=0,g_led=0,b_led=0; break;<br />&nbsp; &nbsp; }<br />&nbsp; &nbsp;if(((PIND &gt;&gt; PD4) &amp; 1) == 0 &amp;&amp; sett==0){brig++;if(brig&gt;255){brig=255;}_delay_ms(1);w=1;times0=times;} <br />&nbsp; &nbsp;if(((PIND &gt;&gt; PD5) &amp; 1) == 0 &amp;&amp; sett==0){brig--;if(brig&lt;1){brig=1;}_delay_ms(1);w=1;times0=times;} <br />&nbsp; &nbsp;if(((PIND &gt;&gt; PD6) &amp; 1) == 0 &amp;&amp; sett==0){sett=1;_delay_ms(300);}<br />&nbsp; &nbsp;if(((PIND &gt;&gt; PD6) &amp; 1) == 0 &amp;&amp; sett==1){sett=0;_delay_ms(300);}&nbsp; &nbsp;</p><p>/////// READ TIME ////////////////////////////////////////////&nbsp; <br />&nbsp; &nbsp;sec =&nbsp; (i2c_read_1bit(ADDR_DS3231,0) &amp; 0x0F) + (((i2c_read_1bit(ADDR_DS3231,0) &amp; 0x70) &gt;&gt; 4) * 10);<br />&nbsp; &nbsp;min =&nbsp; (i2c_read_1bit(ADDR_DS3231,1) &amp; 0x0F) + (((i2c_read_1bit(ADDR_DS3231,1) &amp; 0x70) &gt;&gt; 4) * 10);<br />&nbsp; &nbsp;hour = ((i2c_read_1bit(ADDR_DS3231,2) &amp; 0x0F) + ((i2c_read_1bit(ADDR_DS3231,2) &amp; 0x70) &gt;&gt; 4) * 10);<br />&nbsp; &nbsp;i = hour*100+min;<br />&nbsp; &nbsp;<br />//////////// SET TIME ////////////////////////////////////////////////////////////////////// <br /> if(sett==1){<br />&nbsp; hh=hour;<br />&nbsp; mm=min;<br />&nbsp; if(((PIND &gt;&gt; PD4) &amp; 1) == 0){hh++;if(hh&gt;23){hh=0;}_delay_ms(100);w1=1;} <br />&nbsp; if(((PIND &gt;&gt; PD5) &amp; 1) == 0){mm++;if(mm&gt;59){mm=1;}_delay_ms(100);w1=1;} <br />&nbsp; if(w1==1){w1=0;set_time(21,1,12,26,hh,mm,0);}<br />&nbsp; i = hh*100+mm;<br />&nbsp; }<br />////////// RGB ////////////////////////////////////////////////<br />&nbsp; switch(i/1000){&nbsp; &nbsp;<br />&nbsp; &nbsp; case 0: ws(0,1);ws(3,1);ws(6,1);ws(9,0);ws(12,1);ws(15,1);ws(18,1);break;<br />&nbsp; &nbsp; case 1: ws(0,0);ws(3,0);ws(6,1);ws(9,0);ws(12,0);ws(15,0);ws(18,1);break;<br />&nbsp; &nbsp; case 2: ws(0,0);ws(3,1);ws(6,1);ws(9,1);ws(12,1);ws(15,1);ws(18,0);break;<br />&nbsp; &nbsp; case 3: ws(0,0);ws(3,1);ws(6,1);ws(9,1);ws(12,0);ws(15,1);ws(18,1);break;<br />&nbsp; &nbsp; case 4: ws(0,1);ws(3,0);ws(6,1);ws(9,1);ws(12,0);ws(15,0);ws(18,1);break;<br />&nbsp; &nbsp; case 5: ws(0,1);ws(3,1);ws(6,0);ws(9,1);ws(12,0);ws(15,1);ws(18,1);break;<br />&nbsp; &nbsp; case 6: ws(0,1);ws(3,1);ws(6,0);ws(9,1);ws(12,1);ws(15,1);ws(18,1);break;<br />&nbsp; &nbsp; case 7: ws(0,0);ws(3,1);ws(6,1);ws(9,0);ws(12,0);ws(15,0);ws(18,1);break;<br />&nbsp; &nbsp; case 8: ws(0,1);ws(3,1);ws(6,1);ws(9,1);ws(12,1);ws(15,1);ws(18,1);break;<br />&nbsp; &nbsp; case 9: ws(0,1);ws(3,1);ws(6,1);ws(9,1);ws(12,0);ws(15,1);ws(18,1);break;<br />&nbsp; &nbsp; } <br />&nbsp; switch(i/100%10){&nbsp; &nbsp;<br />&nbsp; &nbsp; case 0: ws(21,1);ws(24,1);ws(27,1);ws(30,0);ws(33,1);ws(36,1);ws(39,1);break;<br />&nbsp; &nbsp; case 1: ws(21,0);ws(24,0);ws(27,1);ws(30,0);ws(33,0);ws(36,0);ws(39,1);break;<br />&nbsp; &nbsp; case 2: ws(21,0);ws(24,1);ws(27,1);ws(30,1);ws(33,1);ws(36,1);ws(39,0);break;<br />&nbsp; &nbsp; case 3: ws(21,0);ws(24,1);ws(27,1);ws(30,1);ws(33,0);ws(36,1);ws(39,1);break;<br />&nbsp; &nbsp; case 4: ws(21,1);ws(24,0);ws(27,1);ws(30,1);ws(33,0);ws(36,0);ws(39,1);break;<br />&nbsp; &nbsp; case 5: ws(21,1);ws(24,1);ws(27,0);ws(30,1);ws(33,0);ws(36,1);ws(39,1);break;<br />&nbsp; &nbsp; case 6: ws(21,1);ws(24,1);ws(27,0);ws(30,1);ws(33,1);ws(36,1);ws(39,1);break;<br />&nbsp; &nbsp; case 7: ws(21,0);ws(24,1);ws(27,1);ws(30,0);ws(33,0);ws(36,0);ws(39,1);break;<br />&nbsp; &nbsp; case 8: ws(21,1);ws(24,1);ws(27,1);ws(30,1);ws(33,1);ws(36,1);ws(39,1);break;<br />&nbsp; &nbsp; case 9: ws(21,1);ws(24,1);ws(27,1);ws(30,1);ws(33,0);ws(37,1);ws(39,1);break;<br />&nbsp; &nbsp; } <br />&nbsp; &nbsp; <br />&nbsp; &nbsp; if(((PIND &gt;&gt; PD2) &amp; 1) == 0 &amp;&amp; sett==0){data_led(42, r_led*brig, g_led*brig, b_led*brig);data_led(43, r_led*brig, g_led*brig, b_led*brig);<br />&nbsp; &nbsp; data_led(44, r_led*brig, g_led*brig, b_led*brig);data_led(45, r_led*brig, g_led*brig, b_led*brig);}<br />&nbsp; &nbsp; else{data_led(42, 0, 0, 0);data_led(43, 0, 0, 0);data_led(44, 0, 0, 0);data_led(45, 0, 0, 0);}<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; if(sett==1){data_led(42, 0, brig, 0);data_led(43, brig, 0, 0);data_led(44, 0, brig, 0);data_led(45, brig, 0, 0);}<br />&nbsp; &nbsp; &nbsp;<br />&nbsp; switch(i/10%10){&nbsp; &nbsp;<br />&nbsp; &nbsp; case 0: ws(46,1);ws(49,1);ws(52,1);ws(55,0);ws(58,1);ws(61,1);ws(64,1);break;<br />&nbsp; &nbsp; case 1: ws(46,0);ws(49,0);ws(52,1);ws(55,0);ws(58,0);ws(61,0);ws(64,1);break;<br />&nbsp; &nbsp; case 2: ws(46,0);ws(49,1);ws(52,1);ws(55,1);ws(58,1);ws(61,1);ws(64,0);break;<br />&nbsp; &nbsp; case 3: ws(46,0);ws(49,1);ws(52,1);ws(55,1);ws(58,0);ws(61,1);ws(64,1);break;<br />&nbsp; &nbsp; case 4: ws(46,1);ws(49,0);ws(52,1);ws(55,1);ws(58,0);ws(61,0);ws(64,1);break;<br />&nbsp; &nbsp; case 5: ws(46,1);ws(49,1);ws(52,0);ws(55,1);ws(58,0);ws(61,1);ws(64,1);break;<br />&nbsp; &nbsp; case 6: ws(46,1);ws(49,1);ws(52,0);ws(55,1);ws(58,1);ws(61,1);ws(64,1);break;<br />&nbsp; &nbsp; case 7: ws(46,0);ws(49,1);ws(52,1);ws(55,0);ws(58,0);ws(61,0);ws(64,1);break;<br />&nbsp; &nbsp; case 8: ws(46,1);ws(49,1);ws(52,1);ws(55,1);ws(58,1);ws(61,1);ws(64,1);break;<br />&nbsp; &nbsp; case 9: ws(46,1);ws(49,1);ws(52,1);ws(55,1);ws(58,0);ws(61,1);ws(64,1);break;<br />&nbsp; &nbsp; }&nbsp; <br />&nbsp; switch(i%10){&nbsp; &nbsp;<br />&nbsp; &nbsp; case 0: ws(67,1);ws(70,1);ws(73,1);ws(76,0);ws(79,1);ws(82,1);ws(85,1);break;<br />&nbsp; &nbsp; case 1: ws(67,0);ws(70,0);ws(73,1);ws(76,0);ws(79,0);ws(82,0);ws(85,1);break;<br />&nbsp; &nbsp; case 2: ws(67,0);ws(70,1);ws(73,1);ws(76,1);ws(79,1);ws(82,1);ws(85,0);break;<br />&nbsp; &nbsp; case 3: ws(67,0);ws(70,1);ws(73,1);ws(76,1);ws(79,0);ws(82,1);ws(85,1);break;<br />&nbsp; &nbsp; case 4: ws(67,1);ws(70,0);ws(73,1);ws(76,1);ws(79,0);ws(82,0);ws(85,1);break;<br />&nbsp; &nbsp; case 5: ws(67,1);ws(70,1);ws(73,0);ws(76,1);ws(79,0);ws(82,1);ws(85,1);break;<br />&nbsp; &nbsp; case 6: ws(67,1);ws(70,1);ws(73,0);ws(76,1);ws(79,1);ws(82,1);ws(85,1);break;<br />&nbsp; &nbsp; case 7: ws(67,0);ws(70,1);ws(73,1);ws(76,0);ws(79,0);ws(82,0);ws(85,1);break;<br />&nbsp; &nbsp; case 8: ws(67,1);ws(70,1);ws(73,1);ws(76,1);ws(79,1);ws(82,1);ws(85,1);break;<br />&nbsp; &nbsp; case 9: ws(67,1);ws(70,1);ws(73,1);ws(76,1);ws(79,0);ws(82,1);ws(85,1);break;<br />&nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; led_rgb();res();<br />&nbsp; &nbsp; _delay_ms(100);</p><p>////// EEPROM ///////////////////<br /> if(times-times0&gt;10000&amp;&amp;w==1){EEPROM_write(0,mode);EEPROM_write(1,brig);w=0;}&nbsp; <br />}} // end loop</p><p>void ws(int ind, bool datt){<br />&nbsp; if(datt==1){data_led(ind, r_led*brig, g_led*brig, b_led*brig);data_led(ind+1, r_led*brig, g_led*brig, b_led*brig);data_led(ind+2, r_led*brig, g_led*brig, b_led*brig);}<br />&nbsp; if(datt==0){data_led(ind, 0, 0, 0);data_led(ind+1, 0, 0, 0);data_led(ind+2, 0, 0, 0);}}<br />&nbsp; <br />void bit_0(){H_BIT;asm(&quot;nop&quot;);asm(&quot;nop&quot;);&nbsp; &nbsp;L_BIT;asm(&quot;nop&quot;);asm(&quot;nop&quot;);asm(&quot;nop&quot;);&nbsp; &nbsp;asm(&quot;nop&quot;);} <br />void bit_1(){H_BIT;asm(&quot;nop&quot;);asm(&quot;nop&quot;);asm(&quot;nop&quot;);asm(&quot;nop&quot;);asm(&quot;nop&quot;);asm(&quot;nop&quot;);asm(&quot;nop&quot;);asm(&quot;nop&quot;);&nbsp; &nbsp;L_BIT;}<br />void bit_w(bool x){if(x) bit_1(); else bit_0();}<br />void res(){_delay_us(100);}<br />void data_led(int num, byte rrr, byte ggg, byte bbb){bb[num]=bbb;rr[num]=rrr;gg[num]=ggg;}<br />void led_rgb(){<br />&nbsp; for(int num_i=0;num_i&lt;LED_MAX;num_i++){ <br />&nbsp; cli();<br />bit_w((bb[num_i] &amp; 0x80)&gt;&gt;7);<br />bit_w((bb[num_i] &amp; 0x40)&gt;&gt;6);<br />bit_w((bb[num_i] &amp; 0x20)&gt;&gt;5);<br />bit_w((bb[num_i] &amp; 0x10)&gt;&gt;4);<br />bit_w((bb[num_i] &amp; 0x08)&gt;&gt;3);<br />bit_w((bb[num_i] &amp; 0x04)&gt;&gt;2);<br />bit_w((bb[num_i] &amp; 0x02)&gt;&gt;1);<br />bit_w((bb[num_i] &amp; 0x01)&gt;&gt;0);<br />&nbsp; <br />bit_w((rr[num_i] &amp; 0x80)&gt;&gt;7);<br />bit_w((rr[num_i] &amp; 0x40)&gt;&gt;6);<br />bit_w((rr[num_i] &amp; 0x20)&gt;&gt;5);<br />bit_w((rr[num_i] &amp; 0x10)&gt;&gt;4);<br />bit_w((rr[num_i] &amp; 0x08)&gt;&gt;3);<br />bit_w((rr[num_i] &amp; 0x04)&gt;&gt;2);<br />bit_w((rr[num_i] &amp; 0x02)&gt;&gt;1);<br />bit_w((rr[num_i] &amp; 0x01)&gt;&gt;0);</p><p>bit_w((gg[num_i] &amp; 0x80)&gt;&gt;7);<br />bit_w((gg[num_i] &amp; 0x40)&gt;&gt;6);<br />bit_w((gg[num_i] &amp; 0x20)&gt;&gt;5);<br />bit_w((gg[num_i] &amp; 0x10)&gt;&gt;4);<br />bit_w((gg[num_i] &amp; 0x08)&gt;&gt;3);<br />bit_w((gg[num_i] &amp; 0x04)&gt;&gt;2);<br />bit_w((gg[num_i] &amp; 0x02)&gt;&gt;1);<br />bit_w((gg[num_i] &amp; 0x01)&gt;&gt;0);<br />&nbsp; &nbsp;sei(); <br />}}</p><p>void set_time(byte years, byte days, byte monts, byte datas, byte hours ,byte minute, byte second){<br />&nbsp; &nbsp; if(second &lt; 255){i2c_write(ADDR_DS3231,0x00,(second/10&lt;&lt;4)+second%10);}<br />&nbsp; &nbsp; if(minute &lt; 255){i2c_write(ADDR_DS3231,0x01,(minute/10&lt;&lt;4)+minute%10);} <br />&nbsp; &nbsp; if(hours &lt; 255){i2c_write(ADDR_DS3231,0x02,(hours/10&lt;&lt;4)+hours%10);}<br />&nbsp; &nbsp; if(days &lt; 255){i2c_write(ADDR_DS3231,0x03,days);}<br />&nbsp; &nbsp; if(datas &lt; 255){i2c_write(ADDR_DS3231,0x04,(datas/10&lt;&lt;4)+datas%10);}<br />&nbsp; &nbsp; if(monts &lt; 255){i2c_write(ADDR_DS3231,0x05,(monts/10&lt;&lt;4)+monts%10);}<br />&nbsp; &nbsp; if(years &lt; 255){i2c_write(ADDR_DS3231,0x06,(years/10&lt;&lt;4)+years%10);}<br />&nbsp; }&nbsp; &nbsp; </p><br /><p>int i2c_read_1bit(byte i2c_addr, byte i2c_reg){<br />&nbsp; &nbsp;TWCR = (1&lt;&lt;TWINT)|(1&lt;&lt;TWSTA)|(1&lt;&lt;TWEN);&nbsp; // START<br />&nbsp; while (!(TWCR &amp; (1&lt;&lt;TWINT)));<br />&nbsp; &nbsp;TWDR = i2c_addr &lt;&lt; 1;<br />&nbsp; &nbsp;TWCR = (1&lt;&lt;TWINT) | (1&lt;&lt;TWEN);<br />&nbsp; while (!(TWCR &amp; (1&lt;&lt;TWINT)));<br />&nbsp; &nbsp;TWDR = i2c_reg;<br />&nbsp; &nbsp;TWCR = (1&lt;&lt;TWINT) | (1&lt;&lt;TWEN);<br />&nbsp; while (!(TWCR &amp; (1&lt;&lt;TWINT)));</p><p>&nbsp; &nbsp;TWCR = (1&lt;&lt;TWINT)|(1&lt;&lt;TWSTA)|(1&lt;&lt;TWEN);&nbsp; // START<br />&nbsp; while (!(TWCR &amp; (1&lt;&lt;TWINT))); <br />&nbsp; &nbsp;TWDR = (i2c_addr &lt;&lt; 1) | 1;<br />&nbsp; &nbsp;TWCR = (1&lt;&lt;TWINT) | (1&lt;&lt;TWEN);<br />&nbsp; while (!(TWCR &amp; (1&lt;&lt;TWINT)));</p><p>&nbsp; &nbsp;TWCR = (1&lt;&lt;TWINT)|(1&lt;&lt;TWEN)|(1&lt;&lt;TWEA); <br />&nbsp; while(~TWCR&amp;(1&lt;&lt;TWINT));<br />&nbsp; &nbsp; byte i2c_data = TWDR; <br />&nbsp; TWCR = (1&lt;&lt;TWINT) | (1&lt;&lt;TWEN);<br />&nbsp; while (!(TWCR &amp; (1&lt;&lt;TWINT)));</p><p>&nbsp; &nbsp;TWCR = (1&lt;&lt;TWINT)|(1&lt;&lt;TWEN)|(1&lt;&lt;TWSTO); // СТОП<br />&nbsp; return i2c_data;<br />&nbsp; } <br />&nbsp; &nbsp;<br /> void i2c_write(byte i2c_addr, byte i2c_reg, byte i2c_dat){<br />&nbsp; &nbsp;TWCR = (1&lt;&lt;TWINT)|(1&lt;&lt;TWSTA)|(1&lt;&lt;TWEN);&nbsp; // START<br />&nbsp; while (!(TWCR &amp; (1&lt;&lt;TWINT)));<br />&nbsp; &nbsp;TWDR = i2c_addr &lt;&lt; 1;<br />&nbsp; &nbsp;TWCR = (1&lt;&lt;TWINT) | (1&lt;&lt;TWEN);<br />&nbsp; while (!(TWCR &amp; (1&lt;&lt;TWINT)));<br />&nbsp; &nbsp;TWDR = i2c_reg;<br />&nbsp; &nbsp;TWCR = (1&lt;&lt;TWINT) | (1&lt;&lt;TWEN);<br />&nbsp; while (!(TWCR &amp; (1&lt;&lt;TWINT)));<br />&nbsp; &nbsp;TWDR = i2c_dat;<br />&nbsp; &nbsp;TWCR = (1&lt;&lt;TWINT) | (1&lt;&lt;TWEN);<br />&nbsp; while (!(TWCR &amp; (1&lt;&lt;TWINT)));<br />&nbsp; &nbsp;TWCR = (1&lt;&lt;TWINT)|(1&lt;&lt;TWEN)|(1&lt;&lt;TWSTO); // СТОП<br />&nbsp; } </p><p>ISR(TIMER0_COMPA_vect) {times++;}// millis = 1 ms&nbsp; &nbsp; &nbsp;</p><p>unsigned char EEPROM_read(unsigned int uiAddress){<br />&nbsp; while(EECR &amp; (1&lt;&lt;EEPE));&nbsp; // проверка готовности EEPROM <br />&nbsp; &nbsp; EEARH = ((uiAddress &amp; 0xF0) &lt;&lt; 2); // регистр адреса H<br />&nbsp; &nbsp; EEARL = uiAddress &amp; 0x0F; // регистр адреса L<br />&nbsp; &nbsp; EECR |= (1&lt;&lt;EERE);// чтение EEPROM<br />&nbsp; &nbsp; return EEDR; // вывод значения<br />}</p><p>void EEPROM_write(unsigned int uiAddress, unsigned char ucData){<br />&nbsp; while(EECR &amp; (1&lt;&lt;EEPE)); // проверка готовности EEPROM <br />&nbsp; &nbsp; EEARH = ((uiAddress &amp; 0xF0) &lt;&lt; 2); // регистр адреса H<br />&nbsp; &nbsp; EEARL = uiAddress &amp; 0x0F; // регистр адреса L<br />&nbsp; &nbsp; EEDR = ucData; // регистр данных <br />&nbsp; &nbsp; EECR |= (1&lt;&lt;EEMPE);// Разрешение записи в EEPROM<br />&nbsp; &nbsp; EECR |= (1&lt;&lt;EEPE); // Запись в EEPROM<br />}</p>]]></description>
			<author><![CDATA[null@example.com (mic1960)]]></author>
			<pubDate>Wed, 12 Jun 2024 17:20:32 +0000</pubDate>
			<guid>http://forum.rcl-radio.ru/viewtopic.php?id=651&amp;action=new</guid>
		</item>
		<item>
			<title><![CDATA[Проблема с компиляцией проекта]]></title>
			<link>http://forum.rcl-radio.ru/viewtopic.php?id=644&amp;action=new</link>
			<description><![CDATA[<p><span class="attention-yellow"></span> <br />Есть отличный проект VU метра на Гитхабе:<br /><a href="https://github.com/adamples/VU_meter/">https://github.com/adamples/VU_meter/</a></p><p>Давно купил SH1106 и SSD1306,&nbsp; всё получилось с авторскими hex. Работает отлично. </p><p>Но вот сейчас купил SH1106&nbsp; которые, почему-то, работают с hex для 1306(с 1106 не работают), но&nbsp; справа полоса засвечивается, очевидно что под названием 1106 китайцы продают что-то иное.</p><p>На Гитхабе писали что это 1309.</p><p>Вот и вопрос к коллегам:</p><p>если есть возможность, можете скомпилировать hex&nbsp; под Атм328 на разные типы индикаторов(1305 и 1309), кроме тех, которые уже есть(1106 и 1306)? </p><p>Готов раскошелиться на бутылку рома, ибо у самого не получается.</p>]]></description>
			<author><![CDATA[null@example.com (Karl2233)]]></author>
			<pubDate>Sun, 19 May 2024 03:52:21 +0000</pubDate>
			<guid>http://forum.rcl-radio.ru/viewtopic.php?id=644&amp;action=new</guid>
		</item>
		<item>
			<title><![CDATA[3 таймера]]></title>
			<link>http://forum.rcl-radio.ru/viewtopic.php?id=621&amp;action=new</link>
			<description><![CDATA[<p>Добрый день!</p><p>на другом форуме человек обратился с просьбой помочь со схемой управления какого то процесса, которая должна обеспечить следующий алгоритм работы</p><p>- нажимается кнопка &quot;пуск&quot;<br />- зажигается светодиод оптопары, дает разрешение на работу процесса и ждет сигнала от датчика<br />- по истечении 500мс, если ничего не происходит, светодиод(разрешение процесса) должен выключится и включиться регулируемая потенциометром пауза длительностью 0.5 - 4 сек, после чего все повторяется (если кнопка &quot;пуск&quot; остается нажатой)<br />- пока есть разрешение(горит светодиод), если пришел сигнал с датчика, должно включиться реле на регулируемое вторым потенциометром время от 10мс до 500мс и затем также включается пауза 0.5-4сек<br />- режим &quot;паза&quot; наступает в любом из следующих случаев, который произойдет раньше:<br />1. отпускание кнопки &quot;пуск&quot;<br />2. истечение времени 500мс, после нажатия и длительного удержания кнопки &quot;пуск&quot;(если ничего не происходит) <br />3. истечение времени 10мс - 500мс после прихода сигнала с датчика</p><p>после окончания паузы 0.5-4 сек если кнопка &quot;пуск&quot; не нажата ничего не происходит, если нажата, то цикл повторяется</p><p>согласно алгоритму я &quot;родил&quot; скетч программы и нарисовал схему</p><br /><p><span class="postimg"><img src="http://forum.rcl-radio.ru/uploads/images/2024/03/0f0f208b3ca3dacd382d4767c712069b.jpg" alt="http://forum.rcl-radio.ru/uploads/images/2024/03/0f0f208b3ca3dacd382d4767c712069b.jpg" /></span> </p><div class="codebox"><pre><code>//       !!!ВНИМАНИЕ!!!
//пины ввода/вывода можно заменить на любые удобные
//только в строках #define !!!
//кроме А0 и А1 - их можно менять на любые аналоговые

#define PUSK_PIN 8      // номер вывода кнопки &quot;пуск&quot;
#define DATCHIK_PIN 9   // номер вывода сигнала датчика 
#define LedPUSK_PIN 10  // номер вывода светодиода &quot;пуск&quot;
#define LedPAUSA_PIN 11 // номер вывода светодиода &quot;пауза&quot;
#define RELE_PIN 12     // номер вывода светодиодa c реле

unsigned long tmr ;     // переменная таймера
unsigned long tmr1 ;    // переменная таймера1

void setup() {
  pinMode(PUSK_PIN, INPUT_PULLUP);    // кнопка пуск
  pinMode(DATCHIK_PIN, INPUT_PULLUP); // !!!сигнал с датчика-&quot;0&quot;!!!
  pinMode(LedPUSK_PIN, OUTPUT);       // индикация пуска
  pinMode(LedPAUSA_PIN, OUTPUT);      // индикация паузы
  pinMode(RELE_PIN, OUTPUT);          // реле и светодиод
}
void loop() {
  if ( digitalRead(PUSK_PIN) == LOW ) //если кнопка пуск нажата
  { delay(20);                  //задержка на дребезг контактов
    digitalWrite(LedPUSK_PIN, HIGH);  // вкл. светодиода &quot;пуск&quot;

    tmr = millis();
tmr:
    if (millis() - tmr &lt; 500) //время включенного светодиода &quot;пуск&quot;
    {
      if ( digitalRead(PUSK_PIN) == HIGH) //пауза если отжата &quot;пуск&quot;
      {
        goto pauza;
      }
      if ( digitalRead(DATCHIK_PIN) == LOW) //если есть сигнал датчика
      {
        digitalWrite(RELE_PIN, HIGH);      // вкл.реле и светодиода

 //время на отключение реле регулировка(мс) переменным резистором
        int t1 =  analogRead(A1) / 2 ;
        tmr1 = millis();
tmr1:
        if (millis() - tmr1 &gt; t1 or
            digitalRead(PUSK_PIN) == HIGH)
        {
          goto pauza;
        }
        goto tmr1;
      }
      goto tmr;
    }
pauza:
    digitalWrite(LedPUSK_PIN, LOW);  // выкл. светодиода &quot;пуск&quot;
    digitalWrite(RELE_PIN, LOW);      //выключение реле
    digitalWrite(LedPAUSA_PIN, HIGH); //индикация паузы
    //регулировка паузы(мс) переменным резистором
    int t0 = 4 * analogRead(A0);
    delay(t0);                         //время паузы
    digitalWrite(LedPAUSA_PIN, LOW);  //конец паузы
  }
}</code></pre></div><br /><p><span class="bbu">все работает! человек остался доволен</span></p><div class="quotebox"><blockquote><p>То что Вы сотворили просто конструктор и очень легко настраиваемый и понимаемый. Такого в интернете я нигде не находил когда искал.</p></blockquote></div><br /><p>но... <strong><span class="bbu">недоволен я</span></strong></p><br /><p>я&nbsp; в программировании профаном себя уже не считаю, но и до программиста мне еще далеко, скажем так я себя оцениваю в программировании как Дилетант(с большой буквы <img src="http://forum.rcl-radio.ru/img/smilies/smile.png" width="15" height="15" alt="smile" /> )</p><p>объясните мне пожалуйста, если не трудно, почему в строках программы</p><p>if (millis() - tmr &lt; 500)</p><p>и</p><p>if (millis() - tmr1 &gt; t1</p><p>которые выполняют в общем то одинаковые действия, для правильной отработки выдержки в первом случае мне пришлось ставить &quot;&lt;&quot;(воспользовавшись методом &quot;научного тыка&quot;),&nbsp; а во втором &quot;&gt; &quot; ???</p><p>у меня уже мозги &quot;кипят&quot; - не понимаю <img src="http://forum.rcl-radio.ru/img/smilies/sad.png" width="15" height="15" alt="sad" /></p><br /><p>и еще, как можно было бы обойтись в данном алгоритме&nbsp; без&nbsp; &quot;goto&quot;?<br />мне без них не удалось реализовать поставленную задачу <img src="http://forum.rcl-radio.ru/img/smilies/sad.png" width="15" height="15" alt="sad" /></p>]]></description>
			<author><![CDATA[null@example.com (v1ct0r)]]></author>
			<pubDate>Sat, 09 Mar 2024 11:40:34 +0000</pubDate>
			<guid>http://forum.rcl-radio.ru/viewtopic.php?id=621&amp;action=new</guid>
		</item>
		<item>
			<title><![CDATA[DAC PCM1796 + CS8416 (Arduino)]]></title>
			<link>http://forum.rcl-radio.ru/viewtopic.php?id=610&amp;action=new</link>
			<description><![CDATA[<p>Привет. Я протестировал этот код, и он работает очень хорошо. <a href="http://rcl-radio.ru/?p=92780">http://rcl-radio.ru/?p=92780</a> <br />Можно ли изменить код для управления двумя PCM1796? В режиме двойного моно. Один PCM1796 для левого канала, другой для правого канала. С кодера активируйте каналы для обоих.</p>]]></description>
			<author><![CDATA[null@example.com (gabiivg)]]></author>
			<pubDate>Mon, 12 Feb 2024 17:44:21 +0000</pubDate>
			<guid>http://forum.rcl-radio.ru/viewtopic.php?id=610&amp;action=new</guid>
		</item>
		<item>
			<title><![CDATA[Эмулятор датчика положения коленчатого вала и распредвала]]></title>
			<link>http://forum.rcl-radio.ru/viewtopic.php?id=580&amp;action=new</link>
			<description><![CDATA[<p>Добрый вечер.Нужна помощь в написании скетча для запуска эбу на столе .С задающим диском синхронизации «60-2».Есть скетч с интернета но там сигнал коленвала срегулировкой оборотов а нужен еще распредвала. Хотелось в перспективе иметь возможность добавлять другие сигналы с другим количеством зубов.Подключить энкодер и LCD1602 для отображения сигнала. </p><div class="codebox"><pre><code>// 1 зуб = 2 полупериодам, т.к. полупериод - это время между сигналами 0 и 1. 2 таких сигнала и составляют импульс, т.е. 1 зуб:
// при 36-зубной шестерни вала, 200 об/мин возможны на полупериоде = 4.2 мс, 5000 об/мин - при 0.168 мс
// при 60-зубной шестерни вала, 200 об/мин возможны на полупериоде = 2.5 мс, 5000 об/мин - при 0.1 мс
// при 60 зубах на шестерне коленвала 1 оборот происходит за 72 мс
// при 36 зубах на шестерне коленвала 1 оборот происходит за 43.2 мс

int gear = 60;                  // кол-во зубов шестрени вала
int poluperiod;               // полупериод (мкс)

void setup()  
{
   pinMode(2, OUTPUT);          // 2 пин назначен на выдачу импульсов
   pinMode(A1, INPUT);          // к входу A1 подключаем потенциометр
}

void loop() {
  int val = analogRead(A1);                       // считываем данные с порта A1 (значения потенциометра от 0 до 1023)
  if (gear == 60){                                // для шестерни с 60 зубами
    poluperiod = map(val, 0, 1023, 2500, 100);     // переводим val в новый диапазон от 2500 мкс до 100 мкс и присваиваем знаение потенциометра полупериоду
  }else if(gear == 36){                           // для шестерни с 36 зубами
    poluperiod = map(val, 0, 1023, 4200, 168);   // переводим val в новый диапазон от 4200 мкс до 168 мкс
  }
   
  for(int a=1; a &lt;= gear - 2; a++){               // gear - 2 - отнимаем 2 пропущенных зуба от кол-ва зубов шестерни
    digitalWrite(2, HIGH); 
    delayMicroseconds(poluperiod);
    digitalWrite(2, LOW);
    delayMicroseconds(poluperiod);
  }
  delayMicroseconds(poluperiod * 4);                          // кол-во импульсов до задержки в 2 импульса = 2 зуба
}</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (sabicoha)]]></author>
			<pubDate>Thu, 21 Sep 2023 18:45:54 +0000</pubDate>
			<guid>http://forum.rcl-radio.ru/viewtopic.php?id=580&amp;action=new</guid>
		</item>
		<item>
			<title><![CDATA[Регулятор громкости и тембра на LC75341 + 0.96' I2C 128X64 OLED (Ardui]]></title>
			<link>http://forum.rcl-radio.ru/viewtopic.php?id=571&amp;action=new</link>
			<description><![CDATA[<p>Отличный проект, liman324 спасибо!<br /><a href="http://m.rcl-radio.ru/?p=112670">http://m.rcl-radio.ru/?p=112670</a></p><p>Одно плохо - дисплей 0,96 мелкий.<br />Собственные попытки переделать скетч под дисплей 1,3 не увенчались успехом.</p><p>Прошу помощи в этом - переделке скетча под дисплей 1,3.<br />С меня ром или коньяк <img src="http://forum.rcl-radio.ru/img/smilies/smile.png" width="15" height="15" alt="smile" /></p>]]></description>
			<author><![CDATA[null@example.com (Karl2233)]]></author>
			<pubDate>Thu, 27 Jul 2023 11:58:09 +0000</pubDate>
			<guid>http://forum.rcl-radio.ru/viewtopic.php?id=571&amp;action=new</guid>
		</item>
	</channel>
</rss>
