DUE - совместимость

ProstoAlex
Offline
Зарегистрирован: 21.01.2015

Коллеги, прошу не пинать сильно )

Есть проект, который не тянет по скорости (цикл примерно 1 секунду).

(SIM800, Nexion, десяток 18b20, DHT22, PZEM, сколько-то цифровых и аналоговых входов-выходов)

Решений вижу два:

1. ставить вторую ардуинку для снятия датчиков 

но здесь проблема в том, что самые затратные - общение с SIM800 и Nextion, а оно - двунаправленное, и нормальный код для связки ардуин может съесть всю экономию времени.

2. ставить Due.

Здесь встает вопрос совместимости модулей с 3,3v на Due. Я правильно понимаю, что если поставить преобразователи уровней типа

https://ru.aliexpress.com/item/Free-shipping-Logic-Level-Converter-3-3V-5V-TTL-bi-directional-conversion-system-for-arduino/32582870692.html?spm=a2g0v.search0604.3.216.473e1d5anxpzCo&ws_ab_test=searchweb0_0,searchweb201602_4_10065_10068_319_317_10696_453_10084_454_10083_433_10618_431_10307_10301_537_536_10902_10059_10884_10889_10887_100031_321_322_10915_10103_10914_10911_10910,searchweb201603_45,ppcSwitch_0&algo_expid=70ff38a9-fe7d-438d-8d17-9d5710673358-31&algo_pvid=70ff38a9-fe7d-438d-8d17-9d5710673358

то проблема уйдет (а SIM800 и так изначально 3,3v (вернее, 3,6))

Плюс придется "покувыркаться" с EEPROM, другими аналоговыми уровнями, и.т.д.

Но меня больше всего пугают библиотеки: я использую OneWire, Time, PZEM004T

Вот кто-нибудь может подсказать - они заведутся на DUE ?

PS: вариант № 3 с оптимизацией кода не предлагать - все, что доступно моим мозгам, уже сделал, и не раз )

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

ProstoAlex пишет:

PS: вариант № 3 с оптимизацией кода не предлагать

Да, я и не предлагаю, просто смешно как-то

ProstoAlex пишет:

(SIM800, Nexion, десяток 18b20, DHT22, PZEM, сколько-то цифровых и аналоговых входов-выходов)

Вот, ознакомьтесь

 

ProstoAlex
Offline
Зарегистрирован: 21.01.2015

ну, сравнивать ассемблер и Си по ресурсоемкости странно...

И да, в прошлой жизни программил на ассемблере немного ).

Но сейчас даже полноценная реализация работы с sim800 и Nextion стала непростой задачяей, поэтому просто проверяю com-порты (буферы) на непустоту и считываю.

И вот тут если работать только по одному порту - все хорошо, а если налепить полную обвязку кода, то изредка (примерно 1 из 20) приемов по портам могу не считать (

 

 

MaksVV
Offline
Зарегистрирован: 06.08.2015

А далласы как читаете? Наверное еще библиотекой DallasTemperature. И код как всегда в секрете?

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

ProstoAlex пишет:

ну, сравнивать ассемблер и Си по ресурсоемкости странно...

Действительно.

mixail844
Offline
Зарегистрирован: 30.04.2012

первое что пришло на ум при таком поставленном вопросе : программа написана в "блокирующем стиле"-

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

так чо если программа написана без учета таких особенностей- хоть core i7 ставьте.

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

ProstoAlex пишет:

ну, сравнивать ассемблер и Си по ресурсоемкости странно...

Ты ничего не понял в той картинке. Сравнивать надо не Си с ассемблером (они то, как раз, вполне сравнимы), а мозги: твои и тех, кто писал программы для AGM. 

Попробуй с этой стороны зайти.

ProstoAlex
Offline
Зарегистрирован: 21.01.2015

ни капли не спорю - професиионал, да и просто знаток справился бы с этой задачей в разы лучше.

Но для меня это (как и у 90% ардуинщиков) хобби с элементами полезной нагрузки. )

Да и паяльник мне ближе, чем программирование )

 

ProstoAlex
Offline
Зарегистрирован: 21.01.2015

MaksVV, mixail844 -

старался делать без блокировок.

По крайней мере, с Далласом - сначала инициирую запрос, а через 30 секунд считываю.

Но и в нем, и тем более - при работе с COM-портами - как минимум десяток миллисекунд приходится ставить delay для считывания буфера.

Код выложить могу, не вопрос (ну посмеетесь немного :)) но только вечером.

inspiritus
Offline
Зарегистрирован: 17.12.2012

Тоже заказал дую, на меге не хватает оперативки и скорость маловата.

только вот мне потребуется rtc и w5100 подключать. Вроде как они были 3.3

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

inspiritus пишет:

Тоже заказал дую, на меге не хватает оперативки и скорость маловата.

лучше блюпилл - дешевле и информации в сети больше

Кроме того - большинство цифровых входов толерантны к 5в - можно смешивать 3.3 и 5в периферию

ProstoAlex
Offline
Зарегистрирован: 21.01.2015

меня сейчас не столько железная часть беспокоит (это решаемо, причем "как" - понятно, бустро и недорого), сколько софтовая, в первую очередь - работа библиотек: OneWire, Time, PZEM004T

ssss
Offline
Зарегистрирован: 01.07.2016

ProstoAlex пишет:

в первую очередь - работа библиотек: OneWire, Time, PZEM004T

С этими либами вы ничего не сварите... они несъедобны для нормального эмбедда... увы...

Забудьте о своей затее... в том виде как вы её видите... хоть время сэкономите...

ProstoAlex
Offline
Зарегистрирован: 21.01.2015

почему?

насколько я понял, PZEM - да, написана криво, с делеями.

А 1-wire чем не нравится?

(мне казалось, что библиотека 18b20 - верх маразма, а 1wire как раз нормальна....)

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

ProstoAlex пишет:

почему?

насколько я понял, PZEM - да, написана криво, с делеями.

А 1-wire чем не нравится?

(мне казалось, что библиотека 18b20 - верх маразма, а 1wire как раз нормальна....)

Ну, для "Arduino style" OneWire действительно вполне нормально написана. Но

void OneWire::write_bit(uint8_t v)
{
	IO_REG_TYPE mask IO_REG_MASK_ATTR = bitmask;
	volatile IO_REG_TYPE *reg IO_REG_BASE_ATTR = baseReg;

	if (v & 1) {
		noInterrupts();
		DIRECT_WRITE_LOW(reg, mask);
		DIRECT_MODE_OUTPUT(reg, mask);	// drive output low
		delayMicroseconds(10);
		DIRECT_WRITE_HIGH(reg, mask);	// drive output high
		interrupts();
		delayMicroseconds(55);
	} else {
		noInterrupts();
		DIRECT_WRITE_LOW(reg, mask);
		DIRECT_MODE_OUTPUT(reg, mask);	// drive output low
		delayMicroseconds(65);
		DIRECT_WRITE_HIGH(reg, mask);	// drive output high
		interrupts();
		delayMicroseconds(5);
	}
}


uint8_t OneWire::read_bit(void)
{
	IO_REG_TYPE mask IO_REG_MASK_ATTR = bitmask;
	volatile IO_REG_TYPE *reg IO_REG_BASE_ATTR = baseReg;
	uint8_t r;

	noInterrupts();
	DIRECT_MODE_OUTPUT(reg, mask);
	DIRECT_WRITE_LOW(reg, mask);
	delayMicroseconds(3);
	DIRECT_MODE_INPUT(reg, mask);	// let pin float, pull up will raise
	delayMicroseconds(10);
	r = DIRECT_READ(reg, mask);
	interrupts();
	delayMicroseconds(53);
	return r;

Как видно, тут не только delay используется, но и прерырывания запрещаются на достаточно долгие периоды.  

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

asam пишет:

Как видно, тут не только delay используется, но и прерырывания запрещаются на достаточно долгие периоды.  

делай и делаймикросекондс - это "две большие разницы" ...и прерывание запрещено аж на 10- 15 мкс. УжОс, ящитаю! ;))) 15 мкс это ведь"достаточно долго"? Правильно я говорю?

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Не поможет ему быстрый процессор. Какой бы он быстрый не был, а ждать в делэях он будет так же как и медленный :) Может че нить двухядерное... ESP32 например :)

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

wdrakula пишет:

asam пишет:

Как видно, тут не только delay используется, но и прерырывания запрещаются на достаточно долгие периоды.  

делай и делаймикросекондс - это "две большие разницы" ...и прерывание запрещено аж на 10- 15 мкс. УжОс, ящитаю! ;))) 15 мкс это ведь"достаточно долго"? Правильно я говорю?

Ну когда  на 15, а когда и на 65. Согласен, что в большинстве случаев это не критично, но случаи бывают разные. Главное же что функция блокирующая, и для чтения температуры требуется больше 6 уже миллисекунд из которых 99 процентов времени  процессор ничего полезного не делает.

 

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

brokly пишет:
Может че нить двухядерное
Тогда уж сразу Summit с его 2,397,824 ядрами. Хотя, при таком программированиии ...:(

ProstoAlex
Offline
Зарегистрирован: 21.01.2015

спасибо, коллеги.

я понял вас, и пойду в сторону связки 2 ардуин - одна для сбора данных, вторая - для логики и работы интерфейсами.

Вот ключевое: "Какой бы он быстрый не был, а ждать в делэях он будет так же как и медленный"

еще раз спасибо за наставление на путь истинный!

(только не надо, что истина - в чистом, красивом и беззадержечном коде - ну не осилю я сам, а давать на сторону - не интересно :))

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

ProstoAlex пишет:
не осилю я сам, а давать на сторону - не интересно :))

Так Вы начинайте, а если заткнётесь, мы с удовольствием поможем. Обещаю помогать только намёками, а не готовым решением. Вот сами и сделаете, заодно и научитесь.

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

ProstoAlex пишет:

спасибо, коллеги.

я понял вас, и пойду в сторону связки 2 ардуин

не ходите туда, это тупик. Вместо связи с модулями будут задержки при связи ардуин.

Нужно учиться писать "чистый, красивый и беззадержечный код" - это единственный выход.

Да и не так это трудно, как вам кажется.

mixail844
Offline
Зарегистрирован: 30.04.2012

b707 пишет:

ProstoAlex пишет:

спасибо, коллеги.

я понял вас, и пойду в сторону связки 2 ардуин

не ходите туда, это тупик. Вместо связи с модулями будут задержки при связи ардуин.

Нужно учиться писать "чистый, красивый и беззадержечный код" - это единственный выход.

Да и не так это трудно, как вам кажется.

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

ProstoAlex
Offline
Зарегистрирован: 21.01.2015

коллеги, вот мой код.

Часть первая - наверное, самая "чистая" - температура :

OneWire  ds(9);

byte DSaddr1[8]={0x28, 0xFF, 0x50, 0x3C, 0xA4, 0x16, 0x05, 0x96}; // столовая 

byte DSaddr2[8]={0x28, 0xFF, 0x67, 0x41, 0xA4, 0x16, 0x05, 0x76}; // улица 

unsigned long LastDSCheckTime, DSCheckInterval=30000;

int DSTemp1, DSTemp2;

uint8_t data[5]; // DHT

void setup() {

// стартуем термометры
// сброс шины //выставить адрес // разрешение записать конфиг 
// Th контроль температуры макс 128грд //Tl контроль температуры мин -128грд // 0x60 12-бит разрешение, 0x00 -9бит разрешение
ds.reset(); ds.select(DSaddr1); ds.write(0x4E); ds.write(0x7F); ds.write(0xFF); ds.write(0x60); 
ds.reset(); ds.select(DSaddr2); ds.write(0x4E); ds.write(0x7F); ds.write(0xFF); ds.write(0x60); 
}
void loop() {

// опрос 18b20 -----------------------------------------------------------------------------------------------------------------------------
if (millis () - LastDSCheckTime > DSCheckInterval) {
static boolean n=0; // флаг работы: запрос t + отправка СМС или чтение t
n=!n;
if (n) {ds.reset();  

    int hum1  = 0, temp1 = 0; // ---------- Сначала DHT --------------
     if(readingDHT()){         //если контрольная сумма верна
      hum1 = (data[0] << 8) | data[1];//считаем Н и Т первого датчика
      temp1 = ((data[2] & 0x7F) << 8) | data[3];
      if(data[2] & 0x80)  temp1 *= -1;
    }else{ 
      //ошибка DHT1
    }

                             // ---------сброс шины DS10B20-----------
        ds.select(DSaddr1); ds.write(0x44,0); // начать преобразование (0 - без паразитного питания)
        ds.reset();  ds.select(DSaddr2); ds.write(0x44,0); 

} 
else   {ds.reset();  ds.select(DSaddr1); ds.write(0xBE); DSTemp1 =  (ds.read() | (ds.read()<<8))*10/16; //прочитаны 2 байта           //столовая
Serial.print(round (DSTemp1/10)); Serial.print(round (DSTemp1%10));

ds.reset(); ds.select(DSaddr2); ds.write(0xBE); DSTemp2 =  (ds.read() | (ds.read()<<8))*10/16; //прочитаны 2 байта                - улица 
        DSTemp21 = round (abs(DSTemp2)/10); Serial.print("n11.val="); Serial.print(DSTemp21); 
        DSTemp22 = round (abs(DSTemp2)%10);

      }
LastDSCheckTime = millis();
}