Ви не увійшли.
Все, что нужно, у Вас есть.
1. подключите камеру и монитор к одной ардуине и научитесь выводить изображение
2. подключите радиомодули к двум ардуинам и научитесь передавать информацию по радио
3. объедините одно и другое
Что-то любители пчел по всем форумам активизировались. Видать это жжжжжжжжжжжжжжжж неспроста
А как пользоваться man на вине? Или любишь медок, люби и Linux.Ok?
Скетч: Sketch-i-nastrojjki.zip
--- MultiMediaKnob.ino 2019-11-23 22:40:52.000000000 +0200
+++ MultiMediaKnob.ino 2021-01-22 10:25:15.785897486 +0200
@@ -28,6 +28,8 @@
#define LATCHSTATE 3
int buttonState = HIGH, lastButtonState = HIGH;
+int banMode = 0;
+long banAction = 0;
long lastDebounceTime = 0, debounceDelay = 50, lastAction = 0;
int _position = 0, _positionExt = 0, buttonCounter = 0;
int8_t _oldState; bool shouldActionButton=true, btnReset=true, rotaryMode=false;
@@ -64,21 +66,29 @@
switch (buttonCounter) {
case 0:
// Default Left mode
+ banMode = 0;
TrinketHidCombo.pressMultimediaKey(LEFT_ACTION);
break;
case 1:
// Mode 1 Left
+ if (banMode == 1 && (lastAction - banAction) < 1000)
+ break;
+ banMode = 1;
+ banAction = lastAction;
TrinketHidCombo.pressMultimediaKey(LEFT_ACTION_MODE1);
break;
case 2:
// Mode 2 Left
+ banMode = 0;
TrinketHidCombo.pressMultimediaKey(LEFT_ACTION_MODE2);
break;
case 3:
// Mode 3 Left
+ banMode = 0;
TrinketHidCombo.pressMultimediaKey(LEFT_ACTION_MODE3);
break;
default:
+ banMode = 0;
break;
}
}
@@ -86,21 +96,29 @@
switch (buttonCounter) {
case 0:
// Default Right mode
+ banMode = 0;
TrinketHidCombo.pressMultimediaKey(RIGHT_ACTION);
break;
case 1:
// Mode 1 Right
+ if (banMode == 2 && (lastAction - banAction) < 1000)
+ break;
+ banMode = 2;
+ banAction = lastAction;
TrinketHidCombo.pressMultimediaKey(RIGHT_ACTION_MODE1);
break;
case 2:
// Mode 2 Right
+ banMode = 0;
TrinketHidCombo.pressMultimediaKey(RIGHT_ACTION_MODE2);
break;
case 3:
// Mode 3 Right
+ banMode = 0;
TrinketHidCombo.pressMultimediaKey(RIGHT_ACTION_MODE3);
break;
default:
+ banMode = 0;
break;
}
}
@@ -127,6 +145,7 @@
if ((millis() - lastAction) > buttonPressTimeout) {
if (shouldActionButton) {
+ banMode = 0;
switch (buttonCounter) {
case 0:
break;
Как пользоваться:
man patch
banMode = 2 и banMode == 2 можно заменить на 1, это просто для примера, как реализовать два вида задержек.
Колесо прокрутки можно сделать, пишите в личку.
В 1-wire есть две разные контрольные суммы, одна 8-битная, используется на сетевом уровне (для адресов устройств), а вторая 16-битная, используется на прикладном уровне (для данных).
Посмотрите в заголовочном файле /usr/avr/include/util/crc16.h
8-битная называется _crc_ibutton_update(), 16-битная называется _crc16_update(), там есть и код на C и оптимизированый код на ASM для AVR.
Пример использования кода на C:
#include <stdio.h>
#include <stdint.h>
uint8_t crc8(uint8_t crc, uint8_t data) {
uint8_t i;
crc = crc ^ data;
for (i = 0; i < 8; i++) {
if (crc & 0x01)
crc = (crc >> 1) ^ 0x8C;
else
crc >>= 1;
}
return crc;
}
int main() {
uint8_t addr[8] = {0x28, 0xe8, 0x0b, 0x6c, 0x06, 0x00, 0x00};
uint8_t i, crc = 0;
for (i = 0; i < 7; i++)
crc = crc8(crc, addr[i]);
addr[i] = crc;
printf("%02x%02x%02x%02x%02x%02x%02x%02xn",
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7]);
}
Т.к. фактически алгоритм производит преобразование над результатом (crc ^ data), то можно заранее просчитать для всех значений и сделать табличный вариант:
#include <stdio.h>
#include <stdint.h>
uint8_t crc_tab[256] = {
0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220,
35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98,
190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7,
219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154,
101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36,
248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185,
140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139,
87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53
};
int main() {
uint8_t addr[8] = {0x28, 0xe8, 0x0b, 0x6c, 0x06, 0x00, 0x00};
uint8_t i, crc = 0;
for (i = 0; i < 7; i++)
crc = crc_tab[crc ^ addr[i]];
addr[i] = crc;
printf("%02x%02x%02x%02x%02x%02x%02x%02xn",
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7]);
}
Оба кода выводят одинаковый результат для Вашего примера:
28e80b6c060000b5
При компиляции для МК просто подключаете заголовочный файл и используете готовую функцию.
Добрый день! Купил 2 шт Ваших девайсов. Не сканируются по шине OneWire. Что делать?
Ответил по почте, продублирую и здесь тоже:
1. Должна быть вставлена батарейка CR2032 (не аккумулятор LIR2032, а именно батарейка, напряжение на батарейке должно быть до 3.6V), наличие батарейки является обязательным.
2. Для начала запитайте счетчик по линии VCC, напряжение питания должно быть в пределах 4.5-5.5 V
3. На линии DQ также должно быть напряжение 4.5-5.5 V, резистор подтяжки в данном случае подойдет любой, если есть, используйте 1кОм
Если при таком подключении счетчик определяется, можно пробовать отключать VCC и пробовать питать паразитно.
Любой проц моделируется МТ и наоборот.
Наоборот - нет. Для этого понадобится бесконечная память.
Вот тут https://habr.com/ru/post/247663/ кстати сравнение этих двух вариантов С
У обычного С нету setup() и loop() функций ну и код выглядит по другому
Прокатят такие "конвертеры" из "обычного С" в "Ардуино С" ?
extern int setup(void);
extern int loop(void);
int main() { setup(); for (;;) loop(); }
И в обратную сторону
extern int main();
setup() { main(); }
loop() {}
Просто подключаем файл при компиляции.
Из частей hex тоже можно комбинировать и составлять программы.
Там наверное электромагнитный принцип, мне не подходит по ряду причин, как и устрозвуковые датчики.
Такой же принцип изменения индуктивности катушки в присутствии металла, индуктивность измеряется путем измерения резонансной частоты.
Wire.requestFrom(8, 16);
Ищите по запросу "детектор металла", в тех детекторах, с которыми черные археологи ходят, используется точно тот же принцип работы.
Скорее всего в станке уже готовый индуктивный датчик приближения, там и не нужны большие расстояния, датчик нужен чтобы следовать неровностям, т.е. он держится на всегда фиксированном растоянии.
Кстати, расстояние детектирования индуктивным датчиком сопоставимо с размерами катушки, так что в Вашем случае вполне может сработать.
У Вас датчик приближения какой-то конкретный или его необходимо изобрести? Именно для черного металла (феромагнетик) я когда-то экспериментировал с датчиком Холла и расположенным за ним магнитом, при появлении феромагнетика перед датчиком, магнитное поле в промежутке возрастало и это можно было детектировать. К сожалению металл, который нужно было детектировать оказался не феромагнетиком и я эту идею забросил в пользу индуктивного датчика, но в нем принцип действия основан на измерении резонансной частоты, а это требует нескольких десятков замеров АЦП. Расстояния в индуктивном были до сантиметра, а с датчиком Холла уже и не помню, но тоже такого порядка.
Я же писал выше - метод научного тыка)) У меня получается иногда лепить скетчи из кусков чужих и дописывать по аналогии, плюс библиотеки, инструкции к которым есть. Смотрю какие куски кода примерно за что отвечают, изменяю под себя и вроде получается. Уже сделал так несколько уникальных и полезных для себя устройств.
А в чем смысл позиции "не хочу изучать язык программирования"? Он Вам нужен чтобы облегчить жизнь себе самому.
Здесь помогут и совершенно бесплатно, я Вам набросал алгоритм именно по Вашему ТЗ, Вам нужно только понять принцип работы и Вы без труда напишете и для второй кнопки. Возможно кто-то, у кого появится свободное время, поможет уже с написанием программы, если уж Вы так принципиально не хотите изучать язык программирования.
Сейчас Ваша программа выглядит примерно вот так:
loop() {
клавиша = прочитать_клавишу();
for (;;) {
if (клавиша == значение) {
принт("нажата клавиша значение");
}
}
}
То, что в for(;;) {}, должно быть в Вашем void loop() {}. Удалите все и начните писать с нуля, отлаживая поэтапно.
Вот пример, как пользоваться флагами:
uint8_t flag1;
uint32_t mil1, mil1end;
for (;;) {
if (клик1) {
flag1 = 1;
mil1 = millis();
mil1end = mil1 + 60*1000;
}
if (степ1) {
flag1 = 0;
принт("степ1");
}
if (клик2) {
flag1 = 0;
принт("стоп");
}
if (flag1 && millis() >= mil1) {
принт("старт1");
mil1 += 200;
if (mil1 > mil1end) {
flag1 = 0;
}
}
}
Каждое случайное чисно генерируется на основе предыдущего, вот и получается всегда одна и та же последовательность. Тут Вам какраз и пригодится randomSeed()
Возвращаемые значения
случайное число в диапазоне от min до max-1 (long)
Т.е. чтобы вернуло 0..7 нужно вызывать random(0,8)
И еще совет, если последние незагоревшиеся светодиоды "тянут" с загоранием слишком долго и этот эффект не нужен, то можно, например, заранее подготовить порядок включения перетасовкой массива.
Кпд проточного водонагревателя 70% а бойлера 90%
Т.е., скажем, проточный нагреватель на 12кВт бесполезно расходует 12*0.3=3.6кВт на что-то другое кроме нагрева воды? На что?
Да, я понимаю, что просто греть что-то электроэнергией это расточительство, т.к. выгодней бы было эту энергию потратить на перекачку тепла от какого-то другого тела к тому, которое хотим нагреть.
Любой алгоритм будет не оптимальным по простой причине. Он не может предусмотреть будущее. Теоретически оптимальный должен предугадывать сколько и какой температуры необходимо за время необходимое нагревательному элементу для получения этой температуры и объема.
А как Вам такой алгоритм:
Если стояк холодный - включаем бойлер
Если стояк горячий - отключаем бойлер
Если бойлер горячий - переключаем клапан на бойлер
Если бойлер холодный - переключаем клапан на центральное водоснабжение
Пороги "холодный" и "горячий" - разные и подбираются, в промежутке между порогами можно еще как-то поиграться.
Для экономии энергии и времени можно вспомнить про проточный нагреватель
Плюсую, только проточный и только свыше 10кВт, если меньше, то будете плеваться и хаять все проточники подряд. Электросеть, естественно, должна позволять такую нугрузку.
Пики - это всего-лишь "помыл руки", "помыл посуду", а когда душ, то там посерьезнее.