AndreyASUNO

Борьба С Влажностью

19 сообщений в этой теме

AndreyASUNO    0

Здрасте всем!

Имеется гараж с подвалом!

Есть желание избавиться от влаги из помещения как гаража так и подвала!

Расклад такой:

1. Arduino nano

2. LCD 16X2

3. I2C модуль для подключения LCD к 4, 5 ножкам Arduino

4. Вентиляторы - 3 шт. 220В. для вытяжек в квартирах.

5. Релейный модуль на 4 релюшки

Текст программки для зашивки в Аrduino

#include <DHT.h>

#include <Wire.h>

#include <LiquidCrystal_I2C.h>

#define I2C_SDA 4 // I2C модуль для подключения LCD

#define I2C_SLC 5 // I2C модуль для подключения LCD

#define DHTPIN_U 2 // DHT-11 с улицы

#define DHTPIN_G 3 // DHT-11 в гараже

#define DHTPIN_P 6 // DHT-11 в подвале

#define VEN_U 7 // нога управления релюшкой вентилятора В1

#define VEN_G 8 // нога управления релюшкой вентилятора В2

#define VEN_P 9 // нога управления релюшкой вентилятора В3

LiquidCrystal_I2C lcd(0x27,16,2);

#define DHTTYPE DHT11

DHT dht_U(DHTPIN_U, DHTTYPE); //Улица

DHT dht_G(DHTPIN_G, DHTTYPE); //Гараж

DHT dht_P(DHTPIN_P, DHTTYPE); //Подвал

void setup (void)

{

lcd.init();

lcd.backlight();

// Serial.begin(9600);

dht_U.begin();

dht_G.begin();

dht_P.begin();

pinMode (VEN_U,OUTPUT); digitalWrite(VEN_U, LOW);

pinMode (VEN_G,OUTPUT); digitalWrite(VEN_G, LOW);

pinMode (VEN_P,OUTPUT); digitalWrite(VEN_P, LOW);

}

void loop ()

{

float h_U = dht_U.readHumidity();

float t_U = dht_U.readTemperature();

if (isnan(t_U) || isnan(h_U))

{

Serial.println("Failed to read from DHT_U");

} else

{

// Serial.print("Hum:"); Serial.print(h_U); Serial.print(" %\t");

// Serial.print("Tem:"); Serial.print(t_U); Serial.println(" *C");

lcd.print("H_U="); lcd.print(h_U);

lcd.print("T_U="); lcd.print(t_U);

}

if (t_U < 0) digitalWrite(VEN_U, LOW);

if (h_U > 90) digitalWrite(VEN_U, LOW);

float h_G = dht_G.readHumidity();

float t_G = dht_G.readTemperature();

if (isnan(t_G) || isnan(h_G))

{

Serial.println("Failed to read from DHT_G");

} else

{

// Serial.print("Hum:"); Serial.print(h_G); Serial.print(" %\t");

// Serial.print("Tem:"); Serial.print(t_G); Serial.println(" *C");

lcd.print("H_G="); lcd.print(h_G);

lcd.print("T_G="); lcd.print(t_G);

}

if (h_G > h_U) digitalWrite(VEN_U, HIGH);

if (h_G > 90) digitalWrite(VEN_G, LOW);

if (t_G < 0) digitalWrite(VEN_G, LOW);

float h_P = dht_P.readHumidity();

float t_P = dht_P.readTemperature();

if (isnan(t_P) || isnan(h_P))

{

Serial.println("Failed to read from DHT_P");

} else

{

// Serial.print("Hum:"); Serial.print(h_P); Serial.print(" %\t");

// Serial.print("Tem:"); Serial.print(t_P); Serial.println(" *C");

lcd.print("H_P="); lcd.print(h_P);

lcd.print("T_P="); lcd.print(t_P);

}

if (h_P > h_G) digitalWrite(VEN_P, HIGH);

if (t_G < 0) digitalWrite(VEN_G, LOW);

}

Пока жду комплектацию по почте, может подскажете что еще можно учесть и добавить!

post-151627-0-17961300-1420374155_thumb.png

Изменено пользователем AndreyASUNO

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Быстрый заказ печатных плат

Полный цикл производства PCB по низким ценам!

  • x
    мм
Заказать Получить купон на $5.00
AndreyASUNO    0

Схема - приблизительно такая!

Алгоритм:

Поочередный опрос трех датчиков влажности размещенных на улиже в гараже и подвале!

И включение и выключение вентиляторов в зависимости от данных по плажности и температуры!

post-151627-0-24034500-1420377325_thumb.jpg

Изменено пользователем AndreyASUNO

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Rede RED    640

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

http://www.drive2.ru/b/1240725/

и почитай коментарии...

Изменено пользователем Rede RED

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
o_l_e_g    1 613

Датчики влажности, дадут не всюинформацию, нужно еще учитывать градиент температуры.

А вообще, дам совет, идея реализуема, но геморна! Лучше сделать осушитель, и поставить один датчик.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
AndreyASUNO    0

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
_VN_    16

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
o_l_e_g    1 613

Что именно Вы имеете в виду за осушитель ?

Идея не моя, есть патентованное решение. Силикагель, пересыпается постоянно из одной полости в другую. Одна полость нагревается, и силикагель сушится, она сообщаться с атмосферой, таким образом уносится пар. Вторая полость, сообщается с осушаемым пространством. Датчик, стоит на выходе осушенного воздуха, регулируя интенсивность перемешивания и нагрева.

Очень эффективно! Установка в 9 кВт, держит 60% влажность в неотапливаемом помещении в 18000 куб метров, в любое время года.

Для гаража, это будет ватт 40, и то работать будет по мере надобности.

А с градиентом, если в гараже холодно, а на улице потеплело, то по притоку пойдет насыщение, вплоть до росы. Хоть, и сухой снаружи воздух.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Гор    123

На производстве сушат воздух в компрессорной. Блок осушки содержит два "бака":

-один поглощает влагу

-другой в это время нагревается до 140 (уточните в НЕТ) градусов с продувкой воздухом (140 имеет воздух). Автоматика такова - после прогрева силикагеля до 140 нагрев выключается, он считается высушенным. Если воздухом не продувать - это будет неправильно.

-------------------------------

Если силикагель перегреть - будет квака!

Также при вентиляции важно учитывать температуру:

наружную

и внутреннюю

Делать вывод о целесообразности вентиляции *потери тепла!) или же перегрев погреба летом.

По простому:

-при морозе вЫключать вентиляторы,

-летом днём не вентилировать.

Изменено пользователем Гор

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
AndreyASUNO    0

Ну а если под вытяжную трубу в подвале поставить не свечу а керамическую трубку обмотанную нихромом и управление завести на контроллер! Мне кажется это будет более безопасно чем горящая свеча среди стелажей и ящиков!

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Гор    123

Всё нужно КОНТРОЛЛировать, поэтому кроме влажности обязательно учитывать наружную температуру и эвристически "предвидеть" последствия вентилирования (либо невентилирования) при данных условиях, и делать выбор о необходимости и режиме вентилирования, осушения, подогрева... либо закупоривания труб.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
APB    122

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
AndreyASUNO    0

По мере работ по разработки ПО и и самого железа столкнулся с тем что DHT-11 вовольно сильно врут относительно друг друга! Три датчика находять на полутора сантиметровом расстоянии друг от друга дают показания по температуре : 1ый- 32, 2ой- 24, 3тий- 23 градуса! Подскажите кто игрался с DHT-22, они по точности также врут!

Для калибровки датчиков ввел в схему Dallas 18B20! 747605.jpgПолучилась вот такая железка! (Назовем ее блочёк!) Появились три окошка с показаниями датчиков и статистики за последний час работы с дискретой вывода данных в 4 минуты! Добавил расчет точки росы для гаража и подвала, при котором блокируется работа вентиляторов!

747606.jpg, 747608.jpg, 747609.jpg, появился режим принудительной продувки! 747610.jpgи менюшка сводных данных с показанием температур точек росы!747611.jpgКому интересно могу выложить полную рабочую схему и текст прошивки!

Изменено пользователем AndreyASUNO

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
AndreyASUNO    0

#include <Bounce.h>

#include <math.h>

#include <Wire.h>

#include <DHT.h>

#include <LiquidCrystal_I2C.h>

#include <OneWire.h>

#define DHTPIN_U 2 // DHT-11 с улицы

#define DHTPIN_G 3 // DHT-11 в гараже

#define DHTPIN_P 4 // DHT-11 в подвале

#define DL_18B20 5 // Dallas 18B20

#define VEN_U 6 // Включение - выключение вентилятора с улицы в гараж

#define VEN_G 7 // Включение - выключение вентилятора из гаража в подвал

#define VEN_P 8 // Включение - выключение вентилятора из подвала на улицу

#define OBOGREV 9 // Включение - выключение оборгева

#define BUT_LEFT 11 // Кнопка левая

#define BUT_RIGH 10 // Кнопка правая

#define BUZER 12 // Пищалка

#define DHTTYPE DHT11 // тип датчика влажности для библиотеки <DHT.h>

DHT dht_U(DHTPIN_U, DHTTYPE); //сделали датчик для улицы

DHT dht_G(DHTPIN_G, DHTTYPE); //сделали датчик для гаража

DHT dht_P(DHTPIN_P, DHTTYPE); //сделали датчик для подвала

OneWire ds(DL_18B20); // //сделали датчик для гаража калибровочный

Bounce bouncer_BUT_LEFT = Bounce( BUT_LEFT,1); //Создали левую кнопку

Bounce bouncer_BUT_RIGH = Bounce( BUT_RIGH,1); //Создали правую кнопку

LiquidCrystal_I2C lcd(0x27,16,2); //

int h_U, t_U , h_G ; // переменные для влажности

int t_G, h_P , t_P ; // переменные для температуры

int matrix_h_U[17]; int matrix_t_U[17]; //массивы для улицы

int matrix_h_G[17]; int matrix_t_G[17]; //массивы для гаража

int matrix_h_P[17]; int matrix_t_P[17]; //массивы для подваля

int secundy=-1; int i=1; int tackt=0;

const float a=17.27;

const float b=237.7;

double c_G, c_P, c_U, vl_P, vl_G;

int Tochka_Rosy_G, Tochka_Rosy_P,Tochka_Rosy_U;

//---------------------------------------------------------------------------------------------------------

void produvka(void)//принудительная продувка 600 сек по нажатию правой кнопки!

{

lcd.clear();

int door=600;

while (door!=0)

{

digitalWrite(VEN_U, LOW); digitalWrite(VEN_G, LOW); digitalWrite(VEN_P, LOW); digitalWrite(OBOGREV, LOW);

lcd.setCursor(0,0); lcd.print("PRODUVKA 600 Sec");

lcd.setCursor(0,1); lcd.print("OcTalocb "); lcd.print(door); lcd.print(" Sec");

delay(1000);

door--;

}

digitalWrite(VEN_U, HIGH); digitalWrite(VEN_G, HIGH); digitalWrite(VEN_P, HIGH); digitalWrite(OBOGREV, HIGH);

lcd.clear();

}

//-----------------------------------------------------------------------------------------------------------------------------

void matrix_init (void) //заполяем массивы нулями

{int i_matrix=0;

for (i_matrix=0; i_matrix<60; i_matrix++)

{

matrix_h_U[i_matrix]=0; matrix_t_U[i_matrix]=0;

matrix_h_G[i_matrix]=0; matrix_t_G[i_matrix]=0;

matrix_h_P[i_matrix]=0; matrix_t_P[i_matrix]=0;

}

}

//----------------------------------------------------------------------------------------------------------------------------

void datchiki(void)//принятие решения на вкл или выкл релюшек

{

t_U = dht_U.readTemperature()-14;

h_U = dht_U.readHumidity()-2;

t_G = dht_G.readTemperature()-1;

h_G = dht_G.readHumidity();

t_P = dht_P.readTemperature();

h_P = dht_P.readHumidity();

vl_G = double(h_G)/100;

vl_P = double(h_P)/100;

c_G = ((a*t_G)/(b+t_G))+log(vl_G);

Tochka_Rosy_G=int((b*c_G)/(a-c_G));

c_P = ((a*t_P)/(b+t_P))+log(vl_P);

Tochka_Rosy_P=int((b*c_P)/(a-c_P));

int Tochka_Rosy_G_min=Tochka_Rosy_G-2;

int Tochka_Rosy_G_max=Tochka_Rosy_G+2;

int Tochka_Rosy_P_min=Tochka_Rosy_P-2;

int Tochka_Rosy_P_max=Tochka_Rosy_P+2;

if (t_U<0) {digitalWrite(VEN_U, HIGH);}

else

{

if (t_G>Tochka_Rosy_G_min&&t_G<Tochka_Rosy_G_max) digitalWrite(VEN_U, HIGH); else

{

if (h_U>50) digitalWrite(VEN_U, HIGH); else digitalWrite(VEN_U, LOW);

};

};

if (t_G<0) {digitalWrite(VEN_G, HIGH);}

else

{

if (t_P>Tochka_Rosy_P_min&&t_P<Tochka_Rosy_P_max) digitalWrite(VEN_P, HIGH); else

{

if (h_G>50) digitalWrite(VEN_G, HIGH); else digitalWrite(VEN_G, LOW);

};

};

if (t_P<0) digitalWrite(VEN_P, HIGH);

else

{

if (h_P>50) digitalWrite(VEN_P, LOW); else digitalWrite(VEN_P, HIGH);

};

if (t_P<0) digitalWrite(OBOGREV, LOW);

else

{

if (h_P>60) digitalWrite(OBOGREV, LOW); else digitalWrite(OBOGREV, HIGH);

};

}

//--------------------------------------------------------------------------------------------------------------------------------

void svode (void) // сводная таблица с температурами и влажностями со всех трех DHT

{

//-------------------------

t_U = dht_U.readTemperature()-14;

h_U = dht_U.readHumidity()-2;

lcd.setCursor(0,0); lcd.print("T:="); lcd.print(t_U); lcd.print(" ");

lcd.setCursor(0,1); lcd.print("H:="); lcd.print(h_U); lcd.print(" ");

//-------------------------

t_G = dht_G.readTemperature()-1;

h_G = dht_G.readHumidity();

lcd.setCursor(5,0); lcd.print("="); lcd.print(t_G); lcd.print(" ");

lcd.setCursor(5,1); lcd.print("="); lcd.print(h_G); lcd.print(" ");

//--------------------------

t_P = dht_P.readTemperature();

h_P = dht_P.readHumidity();

lcd.setCursor(8,0); lcd.print("="); lcd.print(t_P); lcd.print("Tg=");lcd.print(Tochka_Rosy_G); lcd.print(" ");

lcd.setCursor(8,1); lcd.print("="); lcd.print(h_P); lcd.print("Tp=");lcd.print(Tochka_Rosy_P); lcd.print(" ");

//--------------------------

delay(5000); lcd.clear(); //рисуется 5 сек и перетирает экран

}

//-------------------------------------------------------------------------------------------------------------------------------------------------

void menu_U (void)//получение влажности и температуры с улици

{

t_U = dht_U.readTemperature()-14;

h_U = dht_U.readHumidity()-2;

lcd.setCursor(0,0); lcd.print("OUTDOR:H="); lcd.print(h_U); lcd.print(" T=");lcd.print(t_U);

int a=0;

for (-1; a<16; a++)

{ lcd.setCursor(a,1);

int s =(matrix_h_U[a]/10);

switch (s)

{case 0: lcd.print("\0") ;break;

case 1: lcd.print("\1") ;break;

case 2: lcd.print("\1") ;break;

case 3: lcd.print("\2") ;break;

case 4: lcd.print("\3") ;break;

case 5: lcd.print("\4") ;break;

case 6: lcd.print("\5") ;break;

case 7: lcd.print("\6") ;break;

case 8: lcd.print("\7") ;break; }

}

}

//-----------------------------------------------------------------------------------------------------------------------------------------------

void menu_G(void)//получение влажности и температуры из гаража

{

t_G = dht_G.readTemperature()-1;

h_G = dht_G.readHumidity();

lcd.setCursor(0,0); lcd.print("GARAGE:H="); lcd.print(h_G); lcd.print(" T=");lcd.print(t_G);

int a=0;

for (-1; a<16; a++)

{ lcd.setCursor(a,1);

int s =int(matrix_h_G[a]/10);

switch (s)

{case 0: lcd.print("\0") ;break;

case 1: lcd.print("\1") ;break;

case 2: lcd.print("\1") ;break;

case 3: lcd.print("\2") ;break;

case 4: lcd.print("\3") ;break;

case 5: lcd.print("\4") ;break;

case 6: lcd.print("\5") ;break;

case 7: lcd.print("\6") ;break;

case 8: lcd.print("\7") ;break; }

}

}

//-------------------------------------------------------------------------------------------------------------------------------------------------

void menu_P (void) //получение влажности и температуры из подвала

{

t_P = dht_P.readTemperature();

h_P = dht_P.readHumidity();

lcd.setCursor(0,0); lcd.print("BASEME:H="); lcd.print(h_P); lcd.print(" T=");lcd.print(t_P);

int a=0;

for (-1; a<16; a++)

{

lcd.setCursor(a,1);

int s =int(matrix_h_P[a]/10);

switch (s){

case 0: lcd.print("\0") ;break;

case 1: lcd.print("\1") ;break;

case 2: lcd.print("\1") ;break;

case 3: lcd.print("\2") ;break;

case 4: lcd.print("\3") ;break;

case 5: lcd.print("\4") ;break;

case 6: lcd.print("\5") ;break;

case 7: lcd.print("\6") ;break;

case 8: lcd.print("\7") ;break; }

}

}

//----------------------------------------------------------------------------------------------------------------------------------------------------

void opros_datchikov (void)

{

//------------------------------------

lcd.setCursor(0,0); lcd.print("T:");

t_U = dht_U.readTemperature()-14;

h_U = dht_U.readHumidity()-2;

if (isnan(t_U) || isnan(h_U)) { lcd.print("Fail"); } else { lcd.print(t_U); lcd.setCursor(0,1); lcd.print("H:"); lcd.print(h_U); } ;

//-----------------------------------

lcd.setCursor(4,0); lcd.print("\4");

t_G = dht_G.readTemperature()-1;

h_G = dht_G.readHumidity();

if (isnan(t_G) || isnan(h_G)) { lcd.print("Fail"); } else { lcd.print(t_G); lcd.setCursor(4,1); lcd.print("\4"); lcd.print(h_G); } ;

//-----------------------------------

lcd.setCursor(7,0); lcd.print("\4");

t_P = dht_P.readTemperature();

h_P = dht_P.readHumidity();

if (isnan(t_P) || isnan(h_P)) { lcd.print("Fail"); } else { lcd.print(t_P); lcd.setCursor(7,1); lcd.print("\4"); lcd.print(h_P); } ;

//------------------------------------

byte i; byte present = 0; byte type_s; byte data[12]; byte addr[8]; float celsius;

if ( !ds.search(addr)) { ds.reset_search(); delay(250); return; }

switch (addr[0]) { case 0x10: type_s = 1; break; case 0x28: type_s = 0; break; case 0x22: type_s = 0; break; return;

} ds.reset(); ds.select(addr); ds.write(0x44, 1); delay(1000);

present = ds.reset(); ds.select(addr); ds.write(0xBE);

for ( i = 0; i < 9; i++) { data = ds.read(); } int16_t raw = (data[1] << 8) | data[0];

if (type_s) { raw = raw << 3; if (data[7] == 0x10) { raw = (raw & 0xFFF0) + 12 - data[6]; } } else { byte cfg = (data[4] & 0x60);

if (cfg == 0x00) raw = raw & ~7; else if (cfg == 0x20) raw = raw & ~3; else if (cfg == 0x40) raw = raw & ~1; }

celsius = (float)raw / 16.0;

lcd.setCursor(10,0); lcd.print("\4"); lcd.print(celsius);

lcd.setCursor(10,1); lcd.print("\4"); lcd.print("\6");lcd.print("\4");lcd.print("\2");lcd.print("\5");lcd.print("\7");

//---------------------------------------

}

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

void setup (void)

{

dht_U.begin(); delay(1000);

dht_G.begin(); delay(1000);

dht_P.begin(); delay(1000);

lcd.init();

lcd.backlight(); delay(200);

lcd.noBacklight();

pinMode(VEN_U, OUTPUT); digitalWrite(VEN_U, HIGH);

pinMode(VEN_G, OUTPUT); digitalWrite(VEN_G, HIGH);

pinMode(VEN_P, OUTPUT); digitalWrite(VEN_P, HIGH);

pinMode(OBOGREV, OUTPUT); digitalWrite(OBOGREV, HIGH);

pinMode(BUT_LEFT,INPUT);

pinMode(BUT_RIGH,INPUT);

matrix_init();//заполняем нулями

byte linia_0 [8] = { B00000, B00000, B00000, B00000, B00000, B00000, B00000, B11111,}; lcd.createChar(0, linia_0);

byte linia_15[8] = { B00000, B00000, B00000, B00000, B00000, B00000, B11111, B11111,}; lcd.createChar(1, linia_15);

byte linia_30[8] = { B00000, B00000, B00000, B00000, B00000, B11111, B11111, B11111,}; lcd.createChar(2, linia_30);

byte linia_45[8] = { B00000, B00000, B00000, B00000, B11111, B11111, B11111, B11111,}; lcd.createChar(3, linia_45);

byte linia_60[8] = { B00000, B00000, B00000, B11111, B11111, B11111, B11111, B11111,}; lcd.createChar(4, linia_60);

byte linia_75[8] = { B00000, B00000, B11111, B11111, B11111, B11111, B11111, B11111,}; lcd.createChar(5, linia_75);

byte linia_90[8] = { B00000, B11111, B11111, B11111, B11111, B11111, B11111, B11111,}; lcd.createChar(6, linia_90);

byte linia_100[8] = { B11111, B11111, B11111, B11111, B11111, B11111, B11111, B11111,}; lcd.createChar(7, linia_100);

opros_datchikov();

delay(4000);

lcd.clear();

}

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

void loop (void)//вечный цикл в петле

{

datchiki(); //переключаем релюшки в зависимости от показаний датчиков

bouncer_BUT_LEFT.update ( ); int value_BUT_LEFT = bouncer_BUT_LEFT.read();

bouncer_BUT_RIGH.update ( ); int value_BUT_RIGH = bouncer_BUT_RIGH.read();

if ( value_BUT_LEFT == HIGH) { i++; if (i>4) i=1;}

if ( value_BUT_RIGH == HIGH) { produvka();} else {delay(1);}

switch (i)

{

case 1: menu_U() ; break;

case 2: menu_G() ; break;

case 3: menu_P() ; break;

case 4: {svode() ; delay(5000); i=1;} break;

}

tackt++;

//запись в массивы температуры и влажности

if (tackt>=115) // время между циклами записи в массивы порядка 4 минут

{tackt=0; secundy++; if (secundy>15)secundy=0;

matrix_h_U[secundy]=h_U; matrix_t_U[secundy]=t_U;

matrix_h_G[secundy]=h_G; matrix_t_G[secundy]=t_G;

matrix_h_P[secundy]=h_P; matrix_t_P[secundy]=t_P;

tone(12, 2000, 150); } // Попискивание при записи очередных элементов массива */

}

//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
AndreyASUNO    0

В гараже беда! Прикрепил к стене, подключил датчики! Влажность в гараже 92 при температуре +2, в подвале 95 при температуре +4С! Вроде все завертелось закрутилось! Спустя минут 10 от первого включения на LCD начали пропадать столбцы отрисовки! Через 2 часа работы потухло процентов 70, невозможно разобрать ни температуру ни влажность! Беда!

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
В 24.02.2015 в 16:24, AndreyASUNO сказал:

#include <Bounce.h>

#include <math.h>

#include <Wire.h>

#include <DHT.h>

#include <LiquidCrystal_I2C.h>

#include <OneWire.h>

#define DHTPIN_U 2 // DHT-11 с улицы

#define DHTPIN_G 3 // DHT-11 в гараже

#define DHTPIN_P 4 // DHT-11 в подвале

#define DL_18B20 5 // Dallas 18B20

#define VEN_U 6 // Включение - выключение вентилятора с улицы в гараж

#define VEN_G 7 // Включение - выключение вентилятора из гаража в подвал

#define VEN_P 8 // Включение - выключение вентилятора из подвала на улицу

#define OBOGREV 9 // Включение - выключение оборгева

#define BUT_LEFT 11 // Кнопка левая

#define BUT_RIGH 10 // Кнопка правая

#define BUZER 12 // Пищалка

#define DHTTYPE DHT11 // тип датчика влажности для библиотеки <DHT.h>

DHT dht_U(DHTPIN_U, DHTTYPE); //сделали датчик для улицы

DHT dht_G(DHTPIN_G, DHTTYPE); //сделали датчик для гаража

DHT dht_P(DHTPIN_P, DHTTYPE); //сделали датчик для подвала

OneWire ds(DL_18B20); // //сделали датчик для гаража калибровочный

Bounce bouncer_BUT_LEFT = Bounce( BUT_LEFT,1); //Создали левую кнопку

Bounce bouncer_BUT_RIGH = Bounce( BUT_RIGH,1); //Создали правую кнопку

LiquidCrystal_I2C lcd(0x27,16,2); //

int h_U, t_U , h_G ; // переменные для влажности

int t_G, h_P , t_P ; // переменные для температуры

int matrix_h_U[17]; int matrix_t_U[17]; //массивы для улицы

int matrix_h_G[17]; int matrix_t_G[17]; //массивы для гаража

int matrix_h_P[17]; int matrix_t_P[17]; //массивы для подваля

int secundy=-1; int i=1; int tackt=0;

const float a=17.27;

const float b=237.7;

double c_G, c_P, c_U, vl_P, vl_G;

int Tochka_Rosy_G, Tochka_Rosy_P,Tochka_Rosy_U;

//---------------------------------------------------------------------------------------------------------

void produvka(void)//принудительная продувка 600 сек по нажатию правой кнопки!

{

lcd.clear();

int door=600;

while (door!=0)

{

digitalWrite(VEN_U, LOW); digitalWrite(VEN_G, LOW); digitalWrite(VEN_P, LOW); digitalWrite(OBOGREV, LOW);

lcd.setCursor(0,0); lcd.print("PRODUVKA 600 Sec");

lcd.setCursor(0,1); lcd.print("OcTalocb "); lcd.print(door); lcd.print(" Sec");

delay(1000);

door--;

}

digitalWrite(VEN_U, HIGH); digitalWrite(VEN_G, HIGH); digitalWrite(VEN_P, HIGH); digitalWrite(OBOGREV, HIGH);

lcd.clear();

}

//-----------------------------------------------------------------------------------------------------------------------------

void matrix_init (void) //заполяем массивы нулями

{int i_matrix=0;

for (i_matrix=0; i_matrix<60; i_matrix++)

{

matrix_h_U[i_matrix]=0; matrix_t_U[i_matrix]=0;

matrix_h_G[i_matrix]=0; matrix_t_G[i_matrix]=0;

matrix_h_P[i_matrix]=0; matrix_t_P[i_matrix]=0;

}

}

//----------------------------------------------------------------------------------------------------------------------------

void datchiki(void)//принятие решения на вкл или выкл релюшек

{

t_U = dht_U.readTemperature()-14;

h_U = dht_U.readHumidity()-2;

t_G = dht_G.readTemperature()-1;

h_G = dht_G.readHumidity();

t_P = dht_P.readTemperature();

h_P = dht_P.readHumidity();

vl_G = double(h_G)/100;

vl_P = double(h_P)/100;

c_G = ((a*t_G)/(b+t_G))+log(vl_G);

Tochka_Rosy_G=int((b*c_G)/(a-c_G));

c_P = ((a*t_P)/(b+t_P))+log(vl_P);

Tochka_Rosy_P=int((b*c_P)/(a-c_P));

int Tochka_Rosy_G_min=Tochka_Rosy_G-2;

int Tochka_Rosy_G_max=Tochka_Rosy_G+2;

int Tochka_Rosy_P_min=Tochka_Rosy_P-2;

int Tochka_Rosy_P_max=Tochka_Rosy_P+2;

if (t_U<0) {digitalWrite(VEN_U, HIGH);}

else

{

if (t_G>Tochka_Rosy_G_min&&t_G<Tochka_Rosy_G_max) digitalWrite(VEN_U, HIGH); else

{

if (h_U>50) digitalWrite(VEN_U, HIGH); else digitalWrite(VEN_U, LOW);

};

};

if (t_G<0) {digitalWrite(VEN_G, HIGH);}

else

{

if (t_P>Tochka_Rosy_P_min&&t_P<Tochka_Rosy_P_max) digitalWrite(VEN_P, HIGH); else

{

if (h_G>50) digitalWrite(VEN_G, HIGH); else digitalWrite(VEN_G, LOW);

};

};

if (t_P<0) digitalWrite(VEN_P, HIGH);

else

{

if (h_P>50) digitalWrite(VEN_P, LOW); else digitalWrite(VEN_P, HIGH);

};

if (t_P<0) digitalWrite(OBOGREV, LOW);

else

{

if (h_P>60) digitalWrite(OBOGREV, LOW); else digitalWrite(OBOGREV, HIGH);

};

}

//--------------------------------------------------------------------------------------------------------------------------------

void svode (void) // сводная таблица с температурами и влажностями со всех трех DHT

{

//-------------------------

t_U = dht_U.readTemperature()-14;

h_U = dht_U.readHumidity()-2;

lcd.setCursor(0,0); lcd.print("T:="); lcd.print(t_U); lcd.print(" ");

lcd.setCursor(0,1); lcd.print("H:="); lcd.print(h_U); lcd.print(" ");

//-------------------------

t_G = dht_G.readTemperature()-1;

h_G = dht_G.readHumidity();

lcd.setCursor(5,0); lcd.print("="); lcd.print(t_G); lcd.print(" ");

lcd.setCursor(5,1); lcd.print("="); lcd.print(h_G); lcd.print(" ");

//--------------------------

t_P = dht_P.readTemperature();

h_P = dht_P.readHumidity();

lcd.setCursor(8,0); lcd.print("="); lcd.print(t_P); lcd.print("Tg=");lcd.print(Tochka_Rosy_G); lcd.print(" ");

lcd.setCursor(8,1); lcd.print("="); lcd.print(h_P); lcd.print("Tp=");lcd.print(Tochka_Rosy_P); lcd.print(" ");

//--------------------------

delay(5000); lcd.clear(); //рисуется 5 сек и перетирает экран

}

//-------------------------------------------------------------------------------------------------------------------------------------------------

void menu_U (void)//получение влажности и температуры с улици

{

t_U = dht_U.readTemperature()-14;

h_U = dht_U.readHumidity()-2;

lcd.setCursor(0,0); lcd.print("OUTDOR:H="); lcd.print(h_U); lcd.print(" T=");lcd.print(t_U);

int a=0;

for (-1; a<16; a++)

{ lcd.setCursor(a,1);

int s =(matrix_h_U[a]/10);

switch (s)

{case 0: lcd.print("\0") ;break;

case 1: lcd.print("\1") ;break;

case 2: lcd.print("\1") ;break;

case 3: lcd.print("\2") ;break;

case 4: lcd.print("\3") ;break;

case 5: lcd.print("\4") ;break;

case 6: lcd.print("\5") ;break;

case 7: lcd.print("\6") ;break;

case 8: lcd.print("\7") ;break; }

}

}

//-----------------------------------------------------------------------------------------------------------------------------------------------

void menu_G(void)//получение влажности и температуры из гаража

{

t_G = dht_G.readTemperature()-1;

h_G = dht_G.readHumidity();

lcd.setCursor(0,0); lcd.print("GARAGE:H="); lcd.print(h_G); lcd.print(" T=");lcd.print(t_G);

int a=0;

for (-1; a<16; a++)

{ lcd.setCursor(a,1);

int s =int(matrix_h_G[a]/10);

switch (s)

{case 0: lcd.print("\0") ;break;

case 1: lcd.print("\1") ;break;

case 2: lcd.print("\1") ;break;

case 3: lcd.print("\2") ;break;

case 4: lcd.print("\3") ;break;

case 5: lcd.print("\4") ;break;

case 6: lcd.print("\5") ;break;

case 7: lcd.print("\6") ;break;

case 8: lcd.print("\7") ;break; }

}

}

//-------------------------------------------------------------------------------------------------------------------------------------------------

void menu_P (void) //получение влажности и температуры из подвала

{

t_P = dht_P.readTemperature();

h_P = dht_P.readHumidity();

lcd.setCursor(0,0); lcd.print("BASEME:H="); lcd.print(h_P); lcd.print(" T=");lcd.print(t_P);

int a=0;

for (-1; a<16; a++)

{

lcd.setCursor(a,1);

int s =int(matrix_h_P[a]/10);

switch (s){

case 0: lcd.print("\0") ;break;

case 1: lcd.print("\1") ;break;

case 2: lcd.print("\1") ;break;

case 3: lcd.print("\2") ;break;

case 4: lcd.print("\3") ;break;

case 5: lcd.print("\4") ;break;

case 6: lcd.print("\5") ;break;

case 7: lcd.print("\6") ;break;

case 8: lcd.print("\7") ;break; }

}

}

//----------------------------------------------------------------------------------------------------------------------------------------------------

void opros_datchikov (void)

{

//------------------------------------

lcd.setCursor(0,0); lcd.print("T:");

t_U = dht_U.readTemperature()-14;

h_U = dht_U.readHumidity()-2;

if (isnan(t_U) || isnan(h_U)) { lcd.print("Fail"); } else { lcd.print(t_U); lcd.setCursor(0,1); lcd.print("H:"); lcd.print(h_U); } ;

//-----------------------------------

lcd.setCursor(4,0); lcd.print("\4");

t_G = dht_G.readTemperature()-1;

h_G = dht_G.readHumidity();

if (isnan(t_G) || isnan(h_G)) { lcd.print("Fail"); } else { lcd.print(t_G); lcd.setCursor(4,1); lcd.print("\4"); lcd.print(h_G); } ;

//-----------------------------------

lcd.setCursor(7,0); lcd.print("\4");

t_P = dht_P.readTemperature();

h_P = dht_P.readHumidity();

if (isnan(t_P) || isnan(h_P)) { lcd.print("Fail"); } else { lcd.print(t_P); lcd.setCursor(7,1); lcd.print("\4"); lcd.print(h_P); } ;

//------------------------------------

byte i; byte present = 0; byte type_s; byte data[12]; byte addr[8]; float celsius;

if ( !ds.search(addr)) { ds.reset_search(); delay(250); return; }

switch (addr[0]) { case 0x10: type_s = 1; break; case 0x28: type_s = 0; break; case 0x22: type_s = 0; break; return;

} ds.reset(); ds.select(addr); ds.write(0x44, 1); delay(1000);

present = ds.reset(); ds.select(addr); ds.write(0xBE);

for ( i = 0; i < 9; i++) { data = ds.read(); } int16_t raw = (data[1] << 8) | data[0];

if (type_s) { raw = raw << 3; if (data[7] == 0x10) { raw = (raw & 0xFFF0) + 12 - data[6]; } } else { byte cfg = (data[4] & 0x60);

if (cfg == 0x00) raw = raw & ~7; else if (cfg == 0x20) raw = raw & ~3; else if (cfg == 0x40) raw = raw & ~1; }

celsius = (float)raw / 16.0;

lcd.setCursor(10,0); lcd.print("\4"); lcd.print(celsius);

lcd.setCursor(10,1); lcd.print("\4"); lcd.print("\6");lcd.print("\4");lcd.print("\2");lcd.print("\5");lcd.print("\7");

//---------------------------------------

}

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

void setup (void)

{

dht_U.begin(); delay(1000);

dht_G.begin(); delay(1000);

dht_P.begin(); delay(1000);

lcd.init();

lcd.backlight(); delay(200);

lcd.noBacklight();

pinMode(VEN_U, OUTPUT); digitalWrite(VEN_U, HIGH);

pinMode(VEN_G, OUTPUT); digitalWrite(VEN_G, HIGH);

pinMode(VEN_P, OUTPUT); digitalWrite(VEN_P, HIGH);

pinMode(OBOGREV, OUTPUT); digitalWrite(OBOGREV, HIGH);

pinMode(BUT_LEFT,INPUT);

pinMode(BUT_RIGH,INPUT);

matrix_init();//заполняем нулями

byte linia_0 [8] = { B00000, B00000, B00000, B00000, B00000, B00000, B00000, B11111,}; lcd.createChar(0, linia_0);

byte linia_15[8] = { B00000, B00000, B00000, B00000, B00000, B00000, B11111, B11111,}; lcd.createChar(1, linia_15);

byte linia_30[8] = { B00000, B00000, B00000, B00000, B00000, B11111, B11111, B11111,}; lcd.createChar(2, linia_30);

byte linia_45[8] = { B00000, B00000, B00000, B00000, B11111, B11111, B11111, B11111,}; lcd.createChar(3, linia_45);

byte linia_60[8] = { B00000, B00000, B00000, B11111, B11111, B11111, B11111, B11111,}; lcd.createChar(4, linia_60);

byte linia_75[8] = { B00000, B00000, B11111, B11111, B11111, B11111, B11111, B11111,}; lcd.createChar(5, linia_75);

byte linia_90[8] = { B00000, B11111, B11111, B11111, B11111, B11111, B11111, B11111,}; lcd.createChar(6, linia_90);

byte linia_100[8] = { B11111, B11111, B11111, B11111, B11111, B11111, B11111, B11111,}; lcd.createChar(7, linia_100);

opros_datchikov();

delay(4000);

lcd.clear();

}

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

void loop (void)//вечный цикл в петле

{

datchiki(); //переключаем релюшки в зависимости от показаний датчиков

bouncer_BUT_LEFT.update ( ); int value_BUT_LEFT = bouncer_BUT_LEFT.read();

bouncer_BUT_RIGH.update ( ); int value_BUT_RIGH = bouncer_BUT_RIGH.read();

if ( value_BUT_LEFT == HIGH) { i++; if (i>4) i=1;}

if ( value_BUT_RIGH == HIGH) { produvka();} else {delay(1);}

switch (i)

{

case 1: menu_U() ; break;

case 2: menu_G() ; break;

case 3: menu_P() ; break;

case 4: {svode() ; delay(5000); i=1;} break;

}

tackt++;

//запись в массивы температуры и влажности

if (tackt>=115) // время между циклами записи в массивы порядка 4 минут

{tackt=0; secundy++; if (secundy>15)secundy=0;

matrix_h_U[secundy]=h_U; matrix_t_U[secundy]=t_U;

matrix_h_G[secundy]=h_G; matrix_t_G[secundy]=t_G;

matrix_h_P[secundy]=h_P; matrix_t_P[secundy]=t_P;

tone(12, 2000, 150); } // Попискивание при записи очередных элементов массива */

}

//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

хотел применить твой код но вылазит ошибка

 

Arduino: 1.8.3 (Windows 7), Плата:"Arduino Nano, ATmega328"

D:\РґРґРґ\garag\sket4\Garag_v1.1.1\Garag_v1.1.1.ino: In function 'void opros_datchikov()':

Garag_v1.1.1:439: error: incompatible types in assignment of 'uint8_t {aka unsigned char}' to 'byte [12] {aka unsigned char [12]}'

exit status 1
incompatible types in assignment of 'uint8_t {aka unsigned char}' to 'byte [12] {aka unsigned char [12]}'

Этот отчёт будет иметь больше информации с
включенной опцией Файл -> Настройки ->
"Показать подробный вывод во время компиляции"
 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Ваша публикация должна быть проверена модератором

Гость
Вы не авторизованы. Если у вас есть аккаунт, пожалуйста, войдите.
Ответить в тему...

×   Вставлено в виде отформатированного текста.   Восстановить форматирование

  Разрешено не более 75 смайлов.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставить изображения напрямую. Загрузите или вставьте изображения по ссылке.

Загрузка...

  • Похожие публикации

    • Автор: carlogulliani
      Добрый день!
      Столкнулся с такой проблемой, пытаюсь взаимодействовать с чипом AFE4300 по SPI. В дотащите указано, что уровень сигнала 2 - 3 вольта. Подключаю к nrf51 (использует уровень 3.3 вольта), ресетю и пытаюсь прочитать дефолтное значение регистра (0x01C3), в итоге получаю 0xFFFF.
      Перепроверил на Arduino Mega 2560, где уровень сигнала 5 вольт (подключил напрямую без level shifter) и считал свои дефолтные значения. Попробовал также считать другие 4 регистра, все также отлично считалось.
      Вот теперь не пойму, в дотащите указано не верно или у меня что-то не то.
      Еще вопрос про согласовать уровней TXB0108. Пытался через нее прокинуть сигнал от nrf51 (3.3v) на afe4300. Питание А - 3.3в, каналы А к nrf51, питание Б 5в, каналы Б к afe4300, OE к 3.3в. Не завелось, даже анализатор говорит, что MOSI шлет 0xFF, вместо реальных данных. Земля везде общая.
      Правда есть оговорка, как данный уровень ко мне приехал я мог по ошибке запитать Б 3 вольтами, а А 5 вольтами. Но даташит на него говорит, что когда А > Б, это не повреждает чип, хотя А должно быть до 3.6 вольт. Еще мог OE подключить к 5 вольтам. В общем, могли ли мои неразумные операции вывести его из строя???
       
      Еще в даташите указано, что неиспользуемые каналы надо подключить либо к питанию, либо к земле. Это может влиять на то, что я сейчас получаю?
    • Автор: mefi73
      Эта статья является логическим продолжением  вот этой статьи про монохромный OLED дисплей. На этот раз мне в руки достался цветной OLED дисплей, разрешением 96*64 пикселя от магазина Banggood (ссылка на дисплей) Пока не забыл, на странице товара есть ссылка на архив с документацией на дисплей.
      Кроме того достаточно информации по дисплею встречается в сети, так же есть готовые библиотеки для нетерпеливых (от Adafruit, Seeed-Studio и конечно же монстр среди библиотек для дисплеев U8Glib). Я же покажу работу с дисплеем безо всяких библиотек, покажу в среде программирования ArduinoIDE, что бы было понятно новичкам (матерые программисты наверняка разберутся).
      Итак, дисплей может подключаться при помощи параллельных интерфейсов (6800, 8080) и последовательного интерфейса SPI. В модуле, который попал мне в руки, реализован SPI протокол.

      Распиновка слева-направо: 2 вывода для питания, SCL - предназначен для тактового сигнала, SDA - по этому входу в контроллер дисплея поступают данные, RES - предназначен для сброса дисплея, DC (data/command) - логический сигнал на этом входе сообщает дисплею что в данный момент передается, данные или команда (об этом чуть позже подробнее), CS - обычный chip select протокола SPI, низкий уровень на этом входе сообщает дисплею, что данные, поступающие по нему, предназначены именно для дисплея. Подробно вдаваться в суть протока SPI я не буду, стоит только уточнить, что дисплей работает в режиме SPI_MODE3 (CPOL=1, CPHA=1).
      Вас могут смутить обозначения SDA и SCL, ведь они применяются для обозначения выводов устройств, работающих по протоколу I2C, но всё на самом деле не так плохо. Поскольку по линии SDA идут данные от микроконтроллера к дисплею - он подключается к выводу MOSI микроконтроллера (D11 на ардуино). По SCL идут тактовые сигналы, а значит он подключается к выводу SCK микроконтроллера (D13 на ардуино).
      Для выводов RES, DC и CS можно выбрать любые выводы (у меня D10 для CS, D8 для DC и  D9 для RES). Библиотека SPI не будет управлять этими выводами, это придется делать вручную. Разберемся для чего нужен каждый из этих выводов.
      CS - самое простое, логический 0 говорит дисплею о том, что данные предназначены для него, логическая 1 - о том что передача данных завершена.
      RES - служит для сброса дисплея, для этого надо на некоторое время подать на этот вывод логический 0. Это необходимо сделать один раз в начале программы перед инициализацией дисплея.
      DC - логический 0, подаваемый на этот вывод, сообщает дисплею о том, что передаются команды, логическая 1 - передаются данные.
      На основании этого создаем две функции для отправки команды и данных соответственно. 
      #include <SPI.h> const int ss = 10; //slave select const int dc = 8; // data/command data=1 command=0 const int reset = 9; //oled reset=0 void oledCommand(uint8_t val) //общая функция отправки команды дисплею {   digitalWrite(ss, LOW); //slave select устанавливаем в 0, это активирует SPI   digitalWrite(dc, LOW); //DC равен 0, это значит что отправляется команда   SPI.transfer(val); //отправляем команду стандартной функцией библиотеки SPI   digitalWrite(ss, HIGH); //slave select устанавливаем в 1, это означает что работа с SPI завершена } void oledData(uint8_t val) //общая функция отправки данных дисплею {   digitalWrite(ss, LOW); //slave select устанавливаем в 0, это активирует SPI   digitalWrite(dc, HIGH); //DC равен 1, это значит что отправляются данные   SPI.transfer(val); //отправляем данные стандартной функцией библиотеки SPI   digitalWrite(ss, HIGH); //slave select устанавливаем в 1, это означает что работа с SPI завершена } void setup() {  pinMode(ss, OUTPUT);  pinMode(dc, OUTPUT);  pinMode(reset, OUTPUT);  SPI.begin();  SPI.setDataMode(SPI_MODE3);  oledInit(); } void setup() {  pinMode(ss, OUTPUT);  pinMode(dc, OUTPUT);  pinMode(reset, OUTPUT);  SPI.begin();  SPI.setDataMode(SPI_MODE3);  oledInit(); } Обратите внимание на функция oledInit() в предпоследней строке кода. Прежде чем дисплей сможет что-либо выводить на экран, его необходимо настроить (инициализировать). Для этого посылаем команды, приведенные в следующей диаграмме.

      init.PNG
      В программе это будет выглядеть так:
      void oledInit() //функция инициализации дисплея {   digitalWrite(reset, HIGH); //процедура сброса дисплея   delay(100);   digitalWrite(reset, LOW);   delay(100);   digitalWrite(reset, HIGH);   delay(100);   //процедура инициализации дисплея   digitalWrite(ss, LOW);   digitalWrite(dc, LOW);   SPI.transfer(0xAE); //display OFF   SPI.transfer(0xA0); //remap & color depth setting   SPI.transfer(0x72);          //b01110010 расшифровка ниже   /*   b01 - 65k format, (00 -256 color, 10 - 65k color format 2)   1 - enable COM split odd even (0 - disable)   1 - scan COM95 to COM0 (0 - COM0 to COM95) отражение по короткой стороне   0 - disable left-right swaping (1 - enable swaping)   0 - RGB color (1 - BGR color)   1 - RAM column 0 to 95 (0 - 95 to 0)   0 - horizontal address increment (1 - vertical)   */   SPI.transfer(0xA1); //set display start line (0-63)   SPI.transfer(0x0);   SPI.transfer(0xA2); //set vertical offset (0-63)   SPI.transfer(0x0);   SPI.transfer(0xA4); //normal display (A5 - all pixel ON, A6 - all pixel OFF, A7 - inverse display)   SPI.transfer(0xA8); //set MUX ratio N+1 mux   SPI.transfer(0x3F); //default 0x3F   SPI.transfer(0xAD); //select internal Vcc supply   SPI.transfer(0x8E); //default 0x8E   SPI.transfer(0xB0); //set power saving mode   SPI.transfer(0x0B); //default 0x0B (disable power saving mode) 0X1A - enable   SPI.transfer(0xB1); //set reset, pre-charge period   SPI.transfer(0x31); //default 0x31   SPI.transfer(0xB3); //oscillator frequency   SPI.transfer(0xF0); //default 0xF0   SPI.transfer(0x8A); //set second pre-charge color A   SPI.transfer(0x64); //default 0x64   SPI.transfer(0x8B); //set second pre-charge color B   SPI.transfer(0x78); //default 0x78   SPI.transfer(0x8C); //set second pre-charge color C   SPI.transfer(0x64); //default 0x64   SPI.transfer(0xBB); //set pre-charge voltage level   SPI.transfer(0x3A); //default 0x3A   SPI.transfer(0xBE); //set COM deselect voltage level   SPI.transfer(0x3E); //default 0x3E   SPI.transfer(0x87); //set master current   SPI.transfer(0x06); //default 0x06   SPI.transfer(0x81); //set contrast for color A   SPI.transfer(0x91); //default 0x91   SPI.transfer(0x82); //set contrast for color B   SPI.transfer(0x50); //default 0x50   SPI.transfer(0x83); //set contrast for color C   SPI.transfer(0x7D); //default 0x7D   SPI.transfer(0xAF); //display ON, normal mode   digitalWrite(ss, HIGH); } Теперь дисплей готов к выводу изображения. Но стоит рассмотреть некоторые команды. В частности очень важны следующие строки:
      SPI.transfer(0xA0); //remap & color depth setting
      SPI.transfer(0x72); //b01110010 расшифровка ниже
      /* b01 - 65k format, (00 -256 color, 10 - 65k color format 2) - здесь мы выбираем в каком формате будут задаваться цвета и сколько цветов будет возможно использовать
      Поскольку выбираем 65 тысяч цветов, то значение цвета в один байт не поместится, только в два байта.
      1 - enable COM split odd even (0 - disable)
      1 - scan COM95 to COM0 (0 - COM0 to COM95) отражение по короткой стороне
      0 - disable left-right swaping (1 - enable swaping) 0 - RGB color (1 - BGR color) задаем привычный нам формат RGB
      1 - RAM column 0 to 95 (0 - 95 to 0)
      0 - horizontal address increment (1 - vertical) */ Выбираем как будут выводиться данные на дисплей, слева-направо сверху-вниз (привычный нам способ, потому что и пишем так и массивы задаем) или сверху-вниз слева-направо. Эти методы адресации рассмотрены в предыдущей статье, лишь отмечу что мы будем использовать горизонтальную адресацию.
      Поскольку для задания цвета у нас есть всего 2 байта, а формат RGB предполагает 3, то необходимо произвести преобразование. Для красного цвета отводятся первые 5 бит, затем 6 бит зеленого цвета, замыкают 5 бит синего, поэтому функцию преобразования цвета я назвал color565
       
       uint16_t c;   c = r >> 3;   c <<= 6;   c |= g >> 2;   c <<= 5;   c |= b >> 3;   return c;// получаем 16-битное значение цвета и возвращаем его } Поскольку данными необходимо передавать только цвет, то функцию передачи данных можно переделать в функцию передачи цвета, но 16-битное значение цвета необходимо будет разбить на два 8-битных и послать их одно за другим.
      void oledDataColor(uint16_t color) //измененная функция для отправки 16-битного значения цвета {   digitalWrite(ss, LOW);   digitalWrite(dc, HIGH);   SPI.transfer(color >> 8); //разбиваем 16-битное значение на 2 8-битных   SPI.transfer(color);   digitalWrite(ss, HIGH); } Теперь можно рисовать, и начну я с базового элемента любого растрового изображения - пикселя. Для отображения графических примитивов предусмотрены готовые функции, но не для пикселя и окружности, поэтому будем изобретать велосипед.
      Я упоминал про горизонтальную адресацию, команды и данные, и сейчас я свяжу это всё воедино и поведаю как вывести изображение на дисплей (но делать я этого конечно же не буду).
      Представим, что необходимо вывести изображение размером N на N пикселей, левый верхний угол изображения должен находиться в координатах х=X, у=Y. Для этого необходимо выбрать прямоугольную область на дисплее, а затем передать значения цвета пикселей по очереди обходя каждый пиксель изображения слева-направо сверху-вниз. Полученные дисплеем значения цвета так же будут выводиться слева-направо сверху-вниз в пределах выбранной области, и обход пикселей будет таким, как представлен на изображении ниже.

      Для выбора области на дисплее необходимо передать команду 0x15,значения Х и У левого верхнего угла области, затем команду 0x75 и значения Х и У правого нижнего угла области. Все эти значения передаются командами, то есть вывод DC подтянут к нулю. Затем подаем на DC логическую единицу и посылаем значения цвета каждого пикселя. Функции отправки команд, данных и цвета я уже привел. Далее необходимо включить фантазию и принять факт что один пиксель - это изображение состоящее из одного пикселя, и процедуру вывода изображения применить к одному единственному пикселю. В итоге получается вот такая функция:
      //функция задает цвет выбранной точке void oledPixel(uint8_t x, uint8_t y, uint16_t color) {   digitalWrite(ss, LOW);   digitalWrite(dc, LOW);   SPI.transfer(0x15);   SPI.transfer(x);   SPI.transfer(95);   SPI.transfer(0x75);   SPI.transfer(y);   SPI.transfer(63);   delay(1);   digitalWrite(dc, HIGH);   SPI.transfer(color >> 8);   SPI.transfer(color);   delay(1);   digitalWrite(ss, HIGH); } Далее пойдут уже готовые функции для вывода линии, прямоугольника и залитого прямоугольника. 
      //функция отрисовывает линию определенного цвета между двумя указанными координатами void oledLine (uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint16_t color) {   digitalWrite(ss, LOW);   digitalWrite(dc, LOW);   SPI.transfer(0x21);   SPI.transfer(x1); //x start   SPI.transfer(y1); //Y start   SPI.transfer(x2); //X end   SPI.transfer(y2); //Y end   delay(1);   //здесь синтезированный в формат 565 цвет разбирается отбратно   //я понимаю что это костыль, но во первых для задания цвета необходимо использовать один аргумент вместо трех   //а во вторых, я использовал именно такой способ для общего понимания работы с цветом при работе с данным дисплеем   SPI.transfer((color >> 11) & 0x1F); //R color   SPI.transfer((color >> 5) & 0x3F); //G color   SPI.transfer(color & 0x1F); //B color   delay(1);   digitalWrite(ss, HIGH); } //функция рисует прямоугольник заданной высоты ширины и цвета, левый верхний угол прямоугольника задается первыми двумя аргументами void oledRect (uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint16_t colorFrame) {   digitalWrite(ss, LOW);   digitalWrite(dc, LOW);   SPI.transfer(0x26); //настройка заливки прямоугольника   SPI.transfer(0x0); //отключаем заливку прямоугольника   SPI.transfer(0x22);   SPI.transfer(x); //x start   SPI.transfer(y); //Y start   SPI.transfer(x + w); //X end   SPI.transfer(y + h); //Y end   delay(1);   SPI.transfer((colorFrame >> 11) & 0x1F); //R color frame   SPI.transfer((colorFrame >> 5) & 0x3F); //G color   SPI.transfer(colorFrame & 0x1F); //B color   delay(10);   digitalWrite(ss, HIGH); } //то же самое, но прямоугольникк залит определенным цветом (6 аргумент задает цвет заливки) void oledRectFill (uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint16_t colorFrame, uint16_t colorFill) {   digitalWrite(ss, LOW);   digitalWrite(dc, LOW);   SPI.transfer(0x26); //настройка заливки прямоугольника   SPI.transfer(0x1);  //включаем заливку прямоугольника   SPI.transfer(0x22);   SPI.transfer(x); //x start   SPI.transfer(y); //Y start   SPI.transfer(x + w); //X end   SPI.transfer(y + h); //Y end   delay(1);   SPI.transfer((colorFrame >> 11) & 0x1F); //R color frame   SPI.transfer((colorFrame >> 5) & 0x3F); //G color   SPI.transfer(colorFrame & 0x1F); //B color   SPI.transfer((colorFill >> 11) & 0x1F); //R color fill   SPI.transfer((colorFill >> 5) & 0x3F); //G color   SPI.transfer(colorFill & 0x1F); //B color   delay(10);   digitalWrite(ss, HIGH); } Так же предусмотрена функция очистки прямоугольной области дисплея и она же используется для очистки всего дисплея.
      void oledClear(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2) {   digitalWrite(ss, LOW);   digitalWrite(dc, LOW);   SPI.transfer(0x25);   SPI.transfer(x1);   SPI.transfer(y1);   SPI.transfer(x2);   SPI.transfer(y2);   delay(1);   digitalWrite(ss, HIGH); } void oledClearAll() {   oledClear(0, 0, 95, 63); } И ещё команды скролинга дисплея. В них я глубоко не вникал, заставил картинку двигаться вертикально, но не смог заставить двигаться горизонтально. На том и хватит, я вряд ли буду использовать эти команды.
       
      //настройка скролинга дисплея void oledScrollSetup (uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint8_t e) {   digitalWrite(ss, LOW);   digitalWrite(dc, LOW);   SPI.transfer(0x27);   SPI.transfer(a);   SPI.transfer(b);   SPI.transfer(c);   SPI.transfer(d);   SPI.transfer(e);   delay(1);   digitalWrite(ss, HIGH); } void oledScrollOn() {   digitalWrite(ss, LOW);   digitalWrite(dc, LOW);   SPI.transfer(0x2F);   digitalWrite(ss, HIGH); } void oledScrollOff() {   digitalWrite(ss, LOW);   digitalWrite(dc, LOW);   SPI.transfer(0x2E);   digitalWrite(ss, HIGH); } Приведу весь код "скетча".
      #include <SPI.h> const int ss = 10; //slave select const int dc = 8; // data/command data=1 command=0 const int reset = 9; //oled reset=0 void oledCommand(uint8_t val) //общая функция отправки команды дисплею {   digitalWrite(ss, LOW); //slave select устанавливаем в 0, это активирует SPI   digitalWrite(dc, LOW); //DC равен 0, это значит что отправляется команда   SPI.transfer(val); //отправляем команду стандартной функцией библиотеки SPI   digitalWrite(ss, HIGH); //slave select устанавливаем в 1, это означает что работа с SPI завершена } void oledData(uint8_t val) //общая функция отправки данных дисплею {   digitalWrite(ss, LOW); //slave select устанавливаем в 0, это активирует SPI   digitalWrite(dc, HIGH); //DC равен 1, это значит что отправляются данные   SPI.transfer(val); //отправляем данные стандартной функцией библиотеки SPI   digitalWrite(ss, HIGH); //slave select устанавливаем в 1, это означает что работа с SPI завершена } void oledDataColor(uint16_t color) //измененная функция для отправки 16-битного значения цвета {   digitalWrite(ss, LOW);   digitalWrite(dc, HIGH);   SPI.transfer(color >> 8); //разбиваем 16-битное значение на 2 8-битных   SPI.transfer(color);   digitalWrite(ss, HIGH); } void oledInit() //функция инициализации дисплея {   digitalWrite(reset, HIGH); //процедура сброса дисплея   delay(100);   digitalWrite(reset, LOW);   delay(100);   digitalWrite(reset, HIGH);   delay(100);   //процедура инициализации дисплея   digitalWrite(ss, LOW);   digitalWrite(dc, LOW);   SPI.transfer(0xAE); //display OFF   SPI.transfer(0xA0); //remap & color depth setting   SPI.transfer(0x72);          //b01110010 расшифровка ниже   /*   b01 - 65k format, (00 -256 color, 10 - 65k color format 2)   1 - enable COM split odd even (0 - disable)   1 - scan COM95 to COM0 (0 - COM0 to COM95) отражение по короткой стороне   0 - disable left-right swaping (1 - enable swaping)   0 - RGB color (1 - BGR color)   1 - RAM column 0 to 95 (0 - 95 to 0)   0 - horizontal address increment (1 - vertical)   */   SPI.transfer(0xA1); //set display start line (0-63)   SPI.transfer(0x0);   SPI.transfer(0xA2); //set vertical offset (0-63)   SPI.transfer(0x0);   SPI.transfer(0xA4); //normal display (A5 - all pixel ON, A6 - all pixel OFF, A7 - inverse display)   SPI.transfer(0xA8); //set MUX ratio N+1 mux   SPI.transfer(0x3F); //default 0x3F   SPI.transfer(0xAD); //select internal Vcc supply   SPI.transfer(0x8E); //default 0x8E   SPI.transfer(0xB0); //set power saving mode   SPI.transfer(0x0B); //default 0x0B (disable power saving mode) 0X1A - enable   SPI.transfer(0xB1); //set reset, pre-charge period   SPI.transfer(0x31); //default 0x31   SPI.transfer(0xB3); //oscillator frequency   SPI.transfer(0xF0); //default 0xF0   SPI.transfer(0x8A); //set second pre-charge color A   SPI.transfer(0x64); //default 0x64   SPI.transfer(0x8B); //set second pre-charge color B   SPI.transfer(0x78); //default 0x78   SPI.transfer(0x8C); //set second pre-charge color C   SPI.transfer(0x64); //default 0x64   SPI.transfer(0xBB); //set pre-charge voltage level   SPI.transfer(0x3A); //default 0x3A   SPI.transfer(0xBE); //set COM deselect voltage level   SPI.transfer(0x3E); //default 0x3E   SPI.transfer(0x87); //set master current   SPI.transfer(0x06); //default 0x06   SPI.transfer(0x81); //set contrast for color A   SPI.transfer(0x91); //default 0x91   SPI.transfer(0x82); //set contrast for color B   SPI.transfer(0x50); //default 0x50   SPI.transfer(0x83); //set contrast for color C   SPI.transfer(0x7D); //default 0x7D   SPI.transfer(0xAF); //display ON, normal mode   digitalWrite(ss, HIGH); } uint16_t color565(uint8_t r, uint8_t g, uint8_t b) //функция преобразования цвета R8G8B8bit в формат R5G6B5bit {   uint16_t c;   c = r >> 3;   c <<= 6;   c |= g >> 2;   c <<= 5;   c |= b >> 3;   return c;// получаем 16-битное значение цвета и возвращаем его } //функция задает цвет выбранной точке void oledPixel(uint8_t x, uint8_t y, uint16_t color) {   digitalWrite(ss, LOW);   digitalWrite(dc, LOW);   SPI.transfer(0x15);   SPI.transfer(x);   SPI.transfer(95);   SPI.transfer(0x75);   SPI.transfer(y);   SPI.transfer(63);   delay(1);   digitalWrite(dc, HIGH);   SPI.transfer(color >> 8);   SPI.transfer(color);   delay(1);   digitalWrite(ss, HIGH); } void oledSetArea(uint8_t x, uint8_t y, uint8_t w, uint8_t h) {   digitalWrite(ss, LOW);   digitalWrite(dc, LOW);   SPI.transfer(0x15);   SPI.transfer(x);   SPI.transfer(y);   SPI.transfer(0x75);   SPI.transfer(x + w);   SPI.transfer(y + h);   delay(1);   digitalWrite(ss, HIGH); } //функция отрисовывает линию определенного цвета между двумя указанными координатами void oledLine (uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint16_t color) {   digitalWrite(ss, LOW);   digitalWrite(dc, LOW);   SPI.transfer(0x21);   SPI.transfer(x1); //x start   SPI.transfer(y1); //Y start   SPI.transfer(x2); //X end   SPI.transfer(y2); //Y end   delay(1);   //здесь синтезированный в формат 565 цвет разбирается отбратно   //я понимаю что это костыль, но во первых для задания цвета необходимо использовать один аргумент вместо трех   //а во вторых, я использовал именно такой способ для общего понимания работы с цветом при работе с данным дисплеем   SPI.transfer((color >> 11) & 0x1F); //R color   SPI.transfer((color >> 5) & 0x3F); //G color   SPI.transfer(color & 0x1F); //B color   delay(1);   digitalWrite(ss, HIGH); } //функция рисует прямоугольник заданной высоты ширины и цвета, левый верхний угол прямоугольника задается первыми двумя аргументами void oledRect (uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint16_t colorFrame) {   digitalWrite(ss, LOW);   digitalWrite(dc, LOW);   SPI.transfer(0x26); //настройка заливки прямоугольника   SPI.transfer(0x0); //отключаем заливку прямоугольника   SPI.transfer(0x22);   SPI.transfer(x); //x start   SPI.transfer(y); //Y start   SPI.transfer(x + w); //X end   SPI.transfer(y + h); //Y end   delay(1);   SPI.transfer((colorFrame >> 11) & 0x1F); //R color frame   SPI.transfer((colorFrame >> 5) & 0x3F); //G color   SPI.transfer(colorFrame & 0x1F); //B color   delay(10);   digitalWrite(ss, HIGH); } //то же самое, но прямоугольникк залит определенным цветом (6 аргумент задает цвет заливки) void oledRectFill (uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint16_t colorFrame, uint16_t colorFill) {   digitalWrite(ss, LOW);   digitalWrite(dc, LOW);   SPI.transfer(0x26); //настройка заливки прямоугольника   SPI.transfer(0x1);  //включаем заливку прямоугольника   SPI.transfer(0x22);   SPI.transfer(x); //x start   SPI.transfer(y); //Y start   SPI.transfer(x + w); //X end   SPI.transfer(y + h); //Y end   delay(1);   SPI.transfer((colorFrame >> 11) & 0x1F); //R color frame   SPI.transfer((colorFrame >> 5) & 0x3F); //G color   SPI.transfer(colorFrame & 0x1F); //B color   SPI.transfer((colorFill >> 11) & 0x1F); //R color fill   SPI.transfer((colorFill >> 5) & 0x3F); //G color   SPI.transfer(colorFill & 0x1F); //B color   delay(10);   digitalWrite(ss, HIGH); } void oledClear(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2) {   digitalWrite(ss, LOW);   digitalWrite(dc, LOW);   SPI.transfer(0x25);   SPI.transfer(x1);   SPI.transfer(y1);   SPI.transfer(x2);   SPI.transfer(y2);   delay(1);   digitalWrite(ss, HIGH); } void oledClearAll() {   oledClear(0, 0, 95, 63); } //настройка скролинга дисплея void oledScrollSetup (uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint8_t e) {   digitalWrite(ss, LOW);   digitalWrite(dc, LOW);   SPI.transfer(0x27);   SPI.transfer(a);   SPI.transfer(b);   SPI.transfer(c);   SPI.transfer(d);   SPI.transfer(e);   delay(1);   digitalWrite(ss, HIGH); } void oledScrollOn() {   digitalWrite(ss, LOW);   digitalWrite(dc, LOW);   SPI.transfer(0x2F);   digitalWrite(ss, HIGH); } void oledScrollOff() {   digitalWrite(ss, LOW);   digitalWrite(dc, LOW);   SPI.transfer(0x2E);   digitalWrite(ss, HIGH); } void setup() {   pinMode(ss, OUTPUT);   pinMode(dc, OUTPUT);   pinMode(reset, OUTPUT);   SPI.begin();   SPI.setDataMode(SPI_MODE3);   oledInit();   oledClearAll();   randomSeed(millis); } void loop() {  oledClearAll();   oledPixel(10, 10, color565(255, 0, 0));   oledLine(45, 32, 40, 63, color565(0, 255, 0));   oledRectFill(60, 0, 10, 20, color565(0, 0, 255), color565(255, 255, 0));   oledRect(40, 0, 10, 20, color565(255, 255, 0));   int x = 20, y = 31, w = 10, h = 10;   oledSetArea(x, y, w, h);   for (int i = 0; i < (w*h); i++) {     oledDataColor(color565(random(0, 255), random(0, 255), random(0, 255)));   }      delay(5000); } Результат работы на фото (специально сдвинул экспозицию в минус): вывод точки, линии, залитого и пустого прямоугольника и массива из точек случайного цвета.

      Плюсы данного дисплея очевидны: малое потребление из-за отсутствия подсветки, малая толщина дисплея, большие углы обзора, ну и наконец он цветной. Чип SSD1331 позволяет обращаться к каждой точке напрямую ( в отличии от монохромного дисплея на чипе SSD1306), что намного упрощает работу с ним. Ну и библиотеки для этого дисплея уже написаны, а то я тут всё велосипеды изобретаю.
      P.S. В архиве скетч, библиотеки для ArduinoIDE и даташиты.
      SSD1331.rar
    • Автор: CasperReduct
      Заранее извиняюсь если вопрос для многих будет примитивным, но так как в радиотехнике 0  - прошу помощи.
      Итак: есть Arduino mini,  различные датчики, датчик MQ135(потребление ~150mA). Питание: к пинам +5,Gnd припаян Microusb для подключения зарядника от телефона (но также хочу дать возможность запитать от 3 батареек).
      вопрос:
      1. как сделать обвязку чтобы при подключении внешнего источника питания, питание от батареек не тратилось?
      2. MQ135 пишут везде нужно свое питание но если я запитаю от внешнего источника его и ардуино то никаких проблем не возникнет?
      3. надо датчик MQ135 включать периодически допустим раз в 10мин на 2 мин c помощю ардуино, какие элементы могут помочь в этом?(использовать реле мне кажеться как с ружья по воробьям) 
    • Автор: jams
      Привет всем. первый раз держу ардуинку. Поставили такую задачу: На руки дали Arduino Mega 2560 R3   и такую задачу. надо задействовать 8 входов, а остальное выходы оставшиеся (их там много). Надо сделать так что бы эти 8 входов были расширены таким способом.: Допустим на  вход 1 подаем единичку а на другом выходе тоже единичка и так до восьми входов., но далее мы подаем комбинацию вход 1 и 2 вместе подаем по единичке и единичка выходит еще на одном свободном выходе и так со всеми восемью входами. например имеем входы 1,2,3,4,5,6,7,8, и делаем такую комбинацию после того как все выходы исчерпаны по одиночному подключению вход и выход. продолжаем дальше вход1+2=выход9 и так далее: 1+3=10, 1+4=11, 1+5=12... потом 2+2=...2+3...2+4... и так далее пока не закончатся все выходы. Теперь вопрос от человека первый раз державшего на руках вышеописанный девайс: Как это нарисовать в скетче? 
      БлагоДарю!
    • Автор: Макcим
      Привет, прошу помощи что и как сделать.
      Кратко, есть пасека с пчелами небольшая.
      Нужно сделать
      1) Под улей поставить 4 тензодатчика каждый на 50кг (как у напольных электронных весов) через модуль АЦП HX711 
       
      2) Во внутрь улья, датчик влажности и температуры DHT11 (неважно какой) 
       
      Пока всё, есть ещё идея сделать "Частотный анализатор"  что-бы отслеживать состояние семьи ( возбужденное или спокойное) но как это сделать пока понятия не имею, в дальнейшем добавить датчик детонации, когда будет gsm модуль. 
      Не знаю как делать, чтоб Arduino опрашивал датчики с интервалом раз в 2 часа и отправлял результат на rasbery pi 3 а он чтоб составлял хронологию (график изменения) на apache сервере. А я мог подключиться к нему к примеру прямо там в поле через wi-fi с телефона и всё посмотреть.(в дальнейшем добавить gsm модуль и отправлял в инет всю информацию.) Или делать сразу всё на Rasbery pi 3. Но ведь мне так не хватит одного Rasbery pi 3 что бы за питать все датчики от всех ульев. Прошу помощи, совета что и как сделать лучше. Делаю для себя.
  • Сообщения

    • К цифровому, еще хотите добавить шум ДС/ДС? Если уж так не можете отфильтровать. Если принципиально двухполярка, примените низковольтный ОУ и поделите  5 В банальным делителем пополам.  
    • Можно добавить УЗИП на вводе и по желанию на группы в щиток. В некоторых поселениях без такой штуки в ВУ не подключат к ЛЭП . Говорят в нутре у них мощные варисторы и даже от попадания молнии защищают.
    • @Pont 007 Я, признаться, не знаю зачем автору темы это нужно, ну уж коли спросил..., а питание с аудиокарт не видел ни разу, разумеется брать +5 вольт с материнки просто так нельзя, помехи будут жуть. @pips Конечно я работал и с этими микросхемами ещё в советской реинкарнации, названия уж не помню. Что касается тактовой частоты ещё раз говорю она здесь особой роли не играет, все равно по питанию как с +5 так и с -5 надо ставить фильтры. На мой взгляд лучше это LC фильтры, индуктивность типа такой или такой выводом от источника напряжения, а другим выводом на  питание ОУ и конденсатор на землю микрофарад 220 + керамика 0,1 мкФ. Просто рисовать неохота, просто ведь.
    • В "Моделисте-конструкторе" нечто подобное делали - трансформатор для сварочника из электродвижка:   МК 8-1992, стр. 19 МК 1-1996, стр. 11 МК 9-2000, стр. 11
    • wm5102e где стоит: Lenovo Yoga Tablet 2 10-51; Samsung Galaxy S4 GT-I9500; Meizu MX3;
    • @o_l_e_g  Спасибо. Но это вам в соседнюю мою тему, я там с этим вопросом уже обсуждал. )))) Если кратко, то весь цифровой бред (шум питания) который по USB питанию попадает на вход усилителя. А я не знаю как его фильтровать нормально. Да и вообще костыль всё это.   В общем эту тему средней точки, пожалуйста тут не развивайте, если хотите помочь молости прошу, Тема моя ниже по ссылке:   Спасибо за совет, но я что буду приходить к каждому с паяльником со словами "давайте мы сейчас ваш комп разберем, попаяем, а потом продолжим".  В общем ваши предлоложения касательно зачем мне это нужно были не верны, спасибо.