Как зайти в настройки роутера: как войти в роутер и открыть настройки

Как зайти в настройки роутера: как войти в роутер и открыть настройки Роботы

Программирование и обмен данными с «arduino» по wi-fi посредством esp8266 часть первая

Для многих своих любительских поделок я использую микроконтроллеры AVR, как и многие другие домашние пивовары. Используя концепцию Arduino, эти поделки приобретают еще и элегантный вид. Фактически, за 300-400 рублей вы получаете небольшую многослойную плату с маской, шелкографией и полностью подключенной периферией для микроконтроллера (и SMD тоже). Есть также всевозможные модули той же серии Arduino: датчики, контроллеры, дисплеи и вся дополнительная периферия, которая нам так необходима. Опять же, все это по разумной цене и хорошо сделано. Вам не придется создавать что-то на скорую руку.

Но все эти различные любительские работы, конечно же, требуют,

Предварительному программированию.

И потом, при всех видах улучшений, вам все равно придется

перепрошивать

. Преимущество удаленной работы в том, что нет необходимости тащить их к программистам. Благодаря все той же платформе Arduino, здесь также есть множество вариантов: Bluetooth, ZigBee, радиоканалы с собственными протоколами, ИК, и даже Wi-Fi. Беспроводная связь доступна для всех из них. Давайте сосредоточимся на последнем. Есть четыре основные причины:

1: Современность, Интернет вещей!

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

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

Серия микросхем ESP8266 – замечательное устройство, но реализовать все это не так-то просто.

Мы продемонстрируем удаленное программирование и обмен данными с ПК (или любого другого устройства) с устройствами на базе микроконтроллеров AVR на примере манипулятора на сервоприводах. Важно сразу подчеркнуть, что все приведенные ниже программы являются лишь демонстрационными и не имеют никакой коммерческой ценности. Поэтому я не буду жаловаться, что программатор такой некрасивый и не имеет функциональности, или почему не везде есть дополнительные сервисы. Поскольку код открыт, каждый может изменять его по своему усмотрению.

Предполагается, что читатель уже знаком с модулями Arduino, подключением и прошивкой ESP8266. На самом деле, в Интернете есть много материалов, объясняющих основы работы с этими устройствами, и я не хочу повторять их здесь. Для непосвященных в конце статьи есть список полезных ссылок, где вы найдете много информации о том, почему некоторые вещи не работают. Как бывший инженер-электронщик, я могу сказать, что 99% проблем сводятся к следующему:

1. Плохие контакты. Поскольку щиты “Arduino” должны взаимодействовать друг с другом через соединения типа “папа-сын”, а не через пайку, что-то, где-то, обычно, расшатано. Проверьте это. Можно сказать, что в целом наука электроники связана с контактами.

2. Проблемы с питанием. В случае 3,3 вольт не используйте 5 вольт. ESP8266 может иногда дымиться. В отличие от этого, он может без проблем обрабатывать логические сигналы от 5-вольтовых устройств.

3. Недостаточный источник питания. Коварный характер ESP8266 может привести к тому, что он будет потреблять почти триста миллиампер, но может довольствоваться и тридцатью. В результате слабенький стабилизатор 3,3 вольта подключенной вами платы Arduino тут же падает до микроскопического уровня. Вы не можете понять, почему он работает или не работает.

4. Путаница с выходами. Всегда проверяйте, куда идут сигналы. Приемник RXD должен быть подключен к передатчику TXD, так же как передатчик TXD к приемнику RXD, но MOSI должен быть подключен к MOSI, а MISO к MISO, и так далее.

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

6. Программные глюки. Поскольку программное обеспечение для отдельных пользователей пишут одни и те же энтузиасты, иногда возникают баги в самой прошивке или при ее обновлении. Полазьте по соответствующим форумам, в том числе иногда и по англоязычным. Многие наши товарищи утверждали, что чип ESP сырой, как питерская погода, но с другой стороны, есть и мнение, что с 2023 года (год первого выпуска) ситуация неуклонно улучшается (вопреки погоде).

7. Таинственные сбои. Редкость, но нервирует. У меня было устройство “Ардуино”, которое я не мог удаленно прошить. Другими словами, оно шило, но с ошибками. Однако оно шило без ошибок, если был применен шлейф от программатора (но без самого программатора). В ответ на это я впаял конденсатор 15 пФ между выходами данных и тактового генератора. Все заработало. Правда, день был убит.

Итак, давайте начнем с самого простого. У нас есть механическая конечность MechArm (но не такая какую собрал Говард Воловитс) сделанная в Китае и персональный компьютер с Windows. Задача — удаленная прошивка программы и управление ея с компьютера.
Как зайти в настройки роутера: как войти в роутер и открыть настройки
Для управляющего контроллера возьмем симпатичную миниатюрную платку Arduino Nano c камнем ATmega328P. Эта плата прекрасно впихивается внутрь механической руки.
Как зайти в настройки роутера: как войти в роутер и открыть настройки
Теперь определимся каким образом мы её будем программировать. Существуют три основных способа наиболее подходящих для удаленной прошивки: через интерфейс SPI, через встроенный загрузчик, через порт JTAG.

Конечно, загрузчик – самый простой. Это программа, заранее прописанная в FLASH-памяти, которая получает код по определенному протоколу (допустим, через UART) и по специальным командам записывает его в место расположения загруженной программы. Например, так работает загрузчик ARDUINO IDE. После сброса или запуска загрузчика он ждет поступления данных, а если их нет, то выполняет программу с нулевого адреса. При поступлении данных раздел программы обновляется. При следующем сбросе загруженная программа начинает выполняться. Возможно, деталей не так много, но суть такова. Для программирования ТРД нам нужно всего три вывода: RESET сброс, GND земля и приемник ТРД. Как правило, передатчик ТРД также используется для проверки записанной программы, но для простых демонстрационных приложений (а не для использования на атомной электростанции) проверку можно опустить.

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

Кроме того, можно программировать через последовательный интерфейс SPI. Вернее, мы программируем, посылая специальные команды, а затем данные, с помощью вышеупомянутого интерфейса. У нас есть внешний загрузчик, но его нужно записать. Помимо RESET и GND, перенос включает четыре дополнительных выхода: MOSI, MISO – данные, SLK – синхронизация, CS – выбор микросхемы. Как правило, MISO и SS можно удалить. Мы ожидаем только получения данных (проверки программы не будет), и на данный момент у нас только один кристалл.

В каждом подходе есть свои плюсы и минусы (я пропустил JTAG из-за короткого срока жизни человека). Из-за своей лени я не потрудился написать его на ассемблере, и я не нашел ни одного свободного загрузчика (просто не искал).

Для построения беспроводного канала был выбран E SP8266 – микроконтроллер, а точнее целая SoC (System-on-Chip) китайского производителя Espressif. Помимо Wi-Fi, он также поддерживает внешнюю флэш-память для запуска программ. В рамках своего проекта я использовал ESP8266-07 с 512 КБ памяти.

Как зайти в настройки роутера: как войти в роутер и открыть настройки
Вообще годится любая ESP8266, где есть лишние ноги для реализации SPI. Поэтому самая простая ESP8266-01 нам не подойдет, так как у неё разведено совсем мало ножек для портов ввода-вывода. Но с другой стороны разница в цене на них меньше ста рублей, а доступны они одинаково. Ну и большие отладочные платы с ESP, где для удобства разведена куча периферии, нам тоже не годятся, так как не влазят, туда куда мы их хотим впихнуть, в нашу механическую руку.

В этом и заключалась основная суть идеи. Тело программы, которая должна быть загружена в ваш микроконтроллер, передается беспроводным способом (через домашнюю сеть) с компьютера на ESP. Программа непосредственно записывается в FLASH-память микроконтроллера через интерфейс SPI. После перезагрузки он позволяет запустить загруженную программу. ESP должен иметь независимый блок, который также будет обрабатывать обмен данными с микроконтроллером, потому что мы также хотим общаться с контроллером. В частности, мы посылаем сигналы управления сервоприводами после записи программы для запуска манипулятора. Итак, мы хотим поднять на ESP TCP-сервер для передачи программы и UDP-сервер для управления MechArm. Серверы подключаются к домашней сети и внимательно слушают, не хочет ли кто-нибудь загрузить новый код в MechaArm или помахать им перед другим человеком.

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

Какое программное обеспечение будем использовать:

Я разработал все на JAVA и IntelliJ IDEA для ПК. Но в принципе вы можете использовать что угодно, если только вы напишете клиент, который будет отправлять программу для прошивки AVR на ESP8266.

Программы для AVR, которые я пишу в ATMEL STUDIO, написаны на C и редко на ассемблере. По принципу, я никогда не использую скетчи Arduino, потому что любая библиотека, которая мне нужна, может быть написана за час или два при полном понимании того, как она работает. Хотя я пробовал использовать скетчи, они все равно будут подхватывать периферию друг у друга и регулярно глючить, пока у вас не будет операционной системы на AVR. Если сравнивать Arduino IDE с ATMEL STUDIO, то она довольно примитивна. Этот вопрос, конечно, спорный, поскольку студентам и школьникам скетчи наверняка покажутся более приятными и простыми.

Я писал программы для ESP8266 на языке Lua, используя прошивку NodeMCU. Я бы предпочел языки Java и C, но они недоступны на ESP. Язык Lua, если применить его к нашей задаче, освоить несложно. Поскольку мне пришлось загружать программы и отлаживать их на ESP, я взял с собой IDE ESPlorer. Это бесплатный продукт, который можно скачать из дома (продавец заберет). Для использования ESPlorer и записи LUA чип ESP8266 должен быть обновлен до новой базовой прошивки. Для этого мы воспользуемся программой PyFlasher для NODE MCU. Затем мы сможем перепрошить его. Мы создадим прошивку и передадим ее создателям: NodeMCU. Вот более подробная информация об этом процессе:

Сайт прост в использовании и понятен. Мы добавляем в библиотеки поддержку SPI и побитовые операции (в LUA побитовые операции перегружены и малополезны в нашем случае). Библиотеки не следует включать в прошивку, потому что после запуска программного обеспечения на ESP8266 остается очень мало памяти – мизерные 20 кБ.

Конечно, вы можете просто взять готовую прошивку, коих много уже болтается в Интернете, но не рекомендую. Хотя бы потому, что на некоторых нет поддержки битовых операции (а они нам нужны) и нет регулирования скорости передачи данных по SPI.
Соответственно, они передаются по умолчанию со скоростью 40 Мгц делённые на какой-то небольшой коэффициент и поэтому AVR их переваривать не успевает.

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

Когда прошивка готова, нам нужно загрузить ее в ESP8266 вместо базового блока. Для этого нам понадобится простой переходник с USB на UART.

Вместо того чтобы использовать удобный контакт питания 3,3 В на адаптере, мы подключаем TXD к RXD и RXD к TXD. В большинстве случаев ESP8266 будет перегружен. Поэтому мы подаем на него отдельное питание. Затем переводим ESP в режим программирования (GP0 на землю, если вы забыли) и запускаем

NODE MCU PyFlasher

.

Как зайти в настройки роутера: как войти в роутер и открыть настройки

Самое главное – не забыть стереть флэш-память (да, она стирает все данные), иначе, в зависимости от версии прошивки, в памяти после программирования может остаться ненужный хлам, который, в свою очередь, будет закидывать хлам в консоль, пока вы продолжаете работать. Ранее я использовал программу, в которой не было возможности стереть предварительную память, и у меня были ужасные проблемы, потому что ничего не работало. Но открыть его было легко, просто на английском форуме для разработчиков NODE MCU.

Теперь, когда у нас есть необходимое программное обеспечение, мы можем писать, тестировать и отлаживать программы на языке LUA (есть также MicroPython, но я его не использовал), используя полезный API от NODE MCU. Запустите ранее упомянутый ESPlorer.

Как зайти в настройки роутера: как войти в роутер и открыть настройки

Кроме того, настроить его на работу с ESP8266, задать параметры последовательного соединения. Все многократно изложено в Интернете и просто для понимания.

Вот код, который мы загрузим в ESP8266, когда будем писать программу на LUA:

Загрузчик Lua для AVR, записываемый в ESP8266
<b>function InstrProgrammingEnable () -- instruction for MC "enable programming"</b>

p=0
while p<31 do
p=p 1

pin=8  
gpio.write(pin, gpio.LOW)
spi.send(1, 0xAC,0x53)
read = spi.recv( 1, 8)
spi.send(1,0,0)
gpio.write(pin, gpio.HIGH)

     if (string.byte(read)== 83) 
        then     
        print("connection established") 
        p=33
            if(p==31)
            then 
            print("no connection")
            end
        end
    end
end


<b>function ProgrammingDisable ()</b>

pin=2--END OF ESET FOR MK
gpio.mode(pin, gpio.INPUT)

pin=8  
gpio.mode(pin, gpio.INPUT)

pin=5--CLK MASTER for SPI
gpio.mode(pin, gpio.INPUT)

pin=6--MISO MASTER  for SPI
gpio.mode(pin, gpio.INPUT)

pin=7--MOSI MASTER for SPI
gpio.mode(pin, gpio.INPUT)
end


<b>function ProgrammingEnable ()</b>
pin=2-- RESET FOR MK
gpio.mode(pin, gpio.OUTPUT)
gpio.write(pin, gpio.LOW)

pin=2--POZITIV FOR 4MSEC RESET FOR MK
gpio.mode(pin, gpio.OUTPUT)
gpio.write(pin, gpio.HIGH)

tmr.delay(4)
gpio.mode(pin, gpio.OUTPUT)
gpio.write(pin, gpio.LOW)

tmr.delay(25000)
end



<b>function InstrFlashErase() </b>

pin=8  
gpio.write(pin, gpio.LOW)
spi.send(1,0xAC,0x80,0,0)
gpio.write(pin, gpio.HIGH)
tmr.delay(15000)

pin=2--RESET FOR MK
gpio.mode(pin, gpio.OUTPUT)
gpio.write(pin, gpio.HIGH)
tmr.delay(20000)
gpio.write(pin, gpio.LOW)

print( "FLASH is erased")
InstrProgrammingEnable () 
end



<b>function InstrStorePAGE(H, address, data)</b>

pin=8  
gpio.write(pin, gpio.LOW)
spi.send(1,H,0,address,data)
gpio.write(pin, gpio.HIGH)
tmr.delay(500)
end




<b>function InstrWriteFLASH(page_address_low,page_address_high)</b>

pin=8  
gpio.write(pin, gpio.LOW)
spi.send(1,0x4C,page_address_high,page_address_low,0)
gpio.write(pin, gpio.HIGH)
tmr.delay(5000)-- иногда не прописываются флэш при малых задержках
end




<b>function Programming (payload)</b>

pin=8--CS MASTER for SPI
gpio.mode(pin, gpio.OUTPUT, gpio.PULLUP)
pin=4--LED LIGHTS ON LOW
gpio.mode(pin, gpio.OUTPUT)
gpio.write(pin, gpio.LOW)
print(string.len(payload))
page_count = 7 -- пишем 1 килобайт 

for k =0  ,page_count ,1 do--quantity of pages

    for i=0 , 127, 2 do-- -1
    address = i/2
    data=payload:byte(i 1 128*k)
        if data == nil 
        then
        data = 0xff
        end
    InstrStorePAGE(0x40,address,data)
  --  tmr.delay(100)--  otherwise not in time write
    data =payload:byte(i 1 1 128*k)
        if data == nil then
        data = 0xff
        end
    InstrStorePAGE(0x48,address,data)
--    tmr.delay(100)
    end

page_address_low=bit.band(k ,3)*64 -- 3 это двоичное 11
page_address_high=k/4 frame1024*2

tmr.delay(1000)
InstrWriteFLASH(page_address_low,page_address_high)
tmr.wdclr()
end

pin=4--LED
gpio.mode(pin, gpio.OUTPUT)
gpio.write(pin, gpio.HIGH)
end



<b>--MAIN BLOCK</b>



wifi.setmode(wifi.STATION)
--wifi.sta.config("имя сети","пароль") -- set SSID and password of your access point
station_cfg={}
tmr.delay(30000)
station_cfg.ssid="имя сети"
tmr.delay(30000)
station_cfg.pwd="пароль"
tmr.delay(30000)
wifi.sta.config(station_cfg)
tmr.delay(30000)
wifi.sta.connect()
tmr.delay(1000000)
print(wifi.sta.status())
print(wifi.sta.getip())



while ( wifi.sta.status()~=1 ) do
if( wifi.sta.status()==5)
then
break
end
end





sv=net.createServer(net.TCP,30)
tmr.delay(100) 
print("SERVER READY")

sv:listen(4000,function(c)
    c:on("receive", function(c, payload)
        print(payload)
        if (payload =="programrn")
        then
            c:send("readyrn")
            print("ready for programrn")


            spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, spi.DATABITS_8,320,spi.FULLDUPLEX)
            ProgrammingEnable ()
            tmr.delay(100)
            InstrProgrammingEnable ()
            tmr.delay(100)
            InstrFlashErase()
            tmr.delay(100)
            frame1024=0--номер переданого фрей мов


        
            st=net.createServer(net.TCP,30)
            st:listen(4001,function(c)
        
            c:on("receive", function(c, payload)
            tmr.wdclr()
       
            Programming (payload)
            frame1024=frame1024 1
             
            end)
            end)
        end

         
        if (payload =="datarn")
        then

            c:send("readyrn")
            print("ready for datarn")
            srv=net.createServer(net.UDP)
            tmr.delay(1000) 

            pin=10
            gpio.write(pin, gpio.HIGH)

            uart.setup(0,9600,8,0,1,0) 

            srv:listen(5000)
            srv:on("receive", function(srv, pl)
            pl=pl*1
            --print(pl)
            uart.write(0,pl)

            tmr.wdclr()
            end)
        end

     
        if (payload =="stoprn")
        then
            if(st~=nil)
            then
            st:close()
            frame1024=0
            ProgrammingDisable ()
            print("stop program")
            end

           if(srv~=nil) 
           then
           srv:close()
           print("stop data")
           end
           
        end

        
         
    end)
end)
end)

При этом выполняются следующие функции:

Функция InstrProgrammingEnable () – переключает микроконтроллер в режим программирования специальной командой, отправленной по SPI.

Функция ProgrammingEnable () – просто перезагружает AVR на 25 мс перед началом программирования.

Function ProgrammingDisable () – по окончании программирования переведите контакты SPI в ESP8266 в неактивное состояние, чтобы они не мешали выполнению кода на микроконтроллере (в случае их использования)

Функция InstrFlashErase() – стирание флэш-памяти микроконтроллера перед началом программирования. Необходимость этого объяснять не нужно.

Функция InstrStorePAGE(H, адрес, данные) – эта команда записывает программный байт во внутренний буфер микроконтроллера. Тем не менее, это еще не сама флэш-память, поскольку она по-прежнему записывается сюда 128-байтовыми страницами.

Функция InstrWriteFLASH(page_address_low,page_address_high) – но это запись на флэш и она требует времени, обратите внимание на временную задержку 5 000 мкс.

Функция Программирование (полезная нагрузка) – самая большая и важная функция, которая также использует вышеперечисленные функции. Каждый кусок передаваемой программы делится на 1024 байта, байты делятся на байты, а затем создаются адреса. Когда каждому байту присвоен адрес, микроконтроллер инициализирует флэш-запись. Затем он продолжает запись следующего килобайта кода со смещением в адресах, чтобы не перезаписать то, что было записано раньше. Поскольку я изначально пытался отправить всю программу, ESP8266 элементарно исчерпал память, достигнув 6 килобайт, и потерпел крах. Этот блок наиболее удобен тем, что его можно легко разделить на части и передавать по TCP (мы должны получить его от компьютера). Больший размер тоже не нужен, TCP, вы сами знаете, в текущей версии ограничивает передаваемый пакет 1500 или около того байт (но у меня почему-то перевалило за 1440, кажется).

Как будто нет ничего сложного, но нужно обойти несколько “подводных камней”.

Далее следует основной блок. В нем мы:

Войдите в сеть беспроводной связи.

Мы создадим TCP-сервер, который будет слушать три команды:

1. “program” (будем программировать),

2. “данные” (мы будем обмениваться данными),

3. “stop” (всё прекращаем).

Если мы программируем, то сначала инициализируем SPI и создаем еще один TCP-сервер, который получает данные (прошитый программный код) побайтно и вызывает функции программирования микроконтроллера, приведенные ниже. Я понимаю, что создание еще одного сервера выглядит глупо, но это необходимость, поскольку локальный API поддерживает создание только одного сокета, и мы должны отделить команды “program” и “data” от передаваемых данных, поскольку здесь они не являются отдельными байтами.

Например, если нас интересует не программирование, а обмен данными с микроконтроллером, то мы отправим “данные” в виде строки по сети TCP. В ответ будет создан сервер (напомню, что мы управляем механической рукой динамически и нам не нужны задержки с формированием TCP-пакетов, а лучше отправить один байт как целый кадр TCP). Датаграммы UDP будут маленькими и быстро формируемыми.

Затем инициализируется UART, и каждый байт, полученный по беспроводной связи, передается по проводу TXD на микроконтроллер, который должен принять данные, если на нем прошита соответствующая программа. Обмен данными в другом направлении также несложно организовать, но я его еще не реализовал.

В результате выполнения команды “stop” вышеуказанные серверы (кроме самого первого) закрывают соединения, а главный сервер возвращается в состояние ожидания команд “программа” и “данные”.

Интерфейс SPI на ESP8266 эмулируется программно, поэтому порты ввода/вывода для сигналов CS, CLK, MISO, MOSI и RESET (для AVR) могут быть выбраны из любых доступных, а не из тех, что указаны в моем загрузчике. Кроме того, выяснилось, что CS и MISO в этом случае можно отключить, чтобы обеспечить работоспособность системы. Также один вывод используется для светодиода на плате ESP8266, который будет периодически мигать, чтобы показать, что программа все еще выполняется.

Первый запрос к AVR не проверяется на ошибки записи (эта информация просто выводится на консоль), EEPROM не программируется, и прошивается не более 32 КБ, так что еще есть над чем поработать. Скорость передачи данных по SPI составляет около 115 кбит/с, поэтому за несколько секунд он сохраняет почти столько же данных, сколько обычный последовательный программатор (например, ISP500).

Вы можете взять код, написать свои сети и пароли, скомпилировать его в ESplorer, назвать его “init” (для запуска при перезагрузке) и отправить его в ESP8266. Это должно работать. То есть, по крайней мере, будьте программистом беспроводных сетей.

Давайте теперь изучим управляющую сторону вещей, персональный компьютер.

Это означает, что нам нужно загрузить HEX-файл, в который преобразуются ваши программы, написанные в среде ATMEL STUDIO, и отправить его через WI-FI на известный нам порт сокета (в данном случае 4000). Есть одна загвоздка: для отправки нам нужен двоичный BIN, а ATMEL STUDIO дает нам только голову. Есть два способа сделать это: либо вы можете приобрести специальный конвертер, например WinHex, либо сделать свою собственную программу. Я еще не делал этого, но, кажется, это не сложно. Вам нужно вырезать заголовок и сделать что-то еще.

Я придумал программу-загрузчик на JAVA (потому что я не знаю другого языка программирования), работающую в среде IntelliJ IDEA, которая очень хороша и бесплатна. Это TCP-клиент, который ищет серверы ESP8266. После того, как он находит файл по адресу, он соединяется с ним и отправляет ему его копию. Код приведен ниже.

Конечно, здесь много лишнего, всевозможных готовых вещей, которые в принципе не нужны. Если TCP-соединение создано, оно создается. Единственная проблема заключалась в том, что файл не отправлялся равными частями по 1024 байта, что мне, собственно, и требовалось, несмотря на то, что я явно указал размер. Очевидно, существует конечный буфер, к которому JAVA не имеет доступа, который отправляет пакеты произвольного размера, что совершенно неприемлемо для получателя. Первоначально я пытался ввести задержку, чтобы буфер устал ждать несколько фрагментов и отправлял их без изменений. Однако задержка начинала работать через 10 секунд, что, на мой взгляд, было слишком большой задержкой для передачи одного килобайта.

Затем я заметил, что по какой-то причине первый чанк всегда происходит точно по инструкции, а со вторым происходит хаос. Поэтому я сделал так, что клиент открывает соединение, отправляет 1024 байта кода и закрывает соединение. Каждая часть файла отправляется до тех пор, пока не будет отправлен весь файл. Все работало успешно.

Все, что вам нужно сделать, это установить среду выполнения Java на свой компьютер. Хотя я обычно запускаю его прямо из IntelliJ IDEA, чтобы всегда можно было посмотреть, что происходит в консоли (здесь тоже нужна среда Java). Разумнее всего, конечно, сделать графический интерфейс. Есть несколько вещей, которые вам понадобятся, например, окно для выпадения пути к файлу, возможность изменить номер порта и так далее. Все эти данные затем хранятся в исполняемом файле.

Как говорил Коровьев, давайте вернемся к механической конечности MechArm, о которой мы говорили ранее. Теперь есть возможность программировать его дистанционно и управлять им. Сейчас мы перейдем к программе управления микроконтроллером.

В данном случае мы управляем четырьмя сервоприводами. Вот эти.

Привод управляется прямоугольными импульсами с периодом 20 мс (50 Гц) и имеет коэффициент заполнения от 2 до 4%. Другими словами, 2% – это один полный оборот в одну сторону, 4% – в другую. Есть только задача для встроенного в AVR ШИМ.

Как зайти в настройки роутера: как войти в роутер и открыть настройки

Один сервопривод управляет движением вправо-влево, второй перемещает коготь к себе и от себя, третий – вверх и вниз, а четвертый управляет самим когтем, который сжимается и разжимается. С помощью ATMEL STUDIO каждый бит кода компилируется в HEX-файл. Из-за того, что изначально клешня управлялась клавиатурой, подключенной к микроконтроллеру, это выглядит странно. Однако провода уходят в прошлое, мы должны развиваться.

Можно, конечно, использовать эскизы сервоприводов из “ARDUINO”, но мне они не очень понравились. Мои собственные наработки интереснее. Все четыре сервопривода также должны работать одновременно, а не в мультиплексированном режиме, поскольку ШИМ переключается на каждый сервопривод отдельно. Поскольку гравитация не отменена, поднятая конечность мгновенно упадет, если соответствующий сервопривод не получает управляющих импульсов. Возможно, четыре сервопривода не смогут работать одновременно с помощью скетча “ARDUINO”. Однако мы можем написать программу, отвечающую этим требованиям. При отсутствии операционной системы, которая различает агнцев и козлищ, использование скетча конкурирует за периферийные устройства микроконтроллера (и мы даже не знаем заранее, какие из них он будет использовать), что приводит к слишком большому количеству проблем.

Это фактический код, который мы запишем в Arduino Nano через ESP8266-07.

Программа для управление MechArm для микроконтроллера AVRmega328P
#define F_CPU 16000000

#include <avr/io.h>
#include <stdint.h>// стандартные целые числа
#include <avr/interrupt.h>
#include <math.h>	// математика
#include <stdio.h> //стандартный ввод-вывод 
#include <avr/eeprom.h>
#include <setjmp.h>
#include <stdlib.h> //стандартные возможности


#define UART_BAUD_RATE 115200

// счетчик Т1 задает временной интервал 20мс
#define  COUNTER1_OFF TCCR1B=0b00000000 // CS02 CS01 CS00 - 000 - отключен; 001  без делителя; 010 c делителем 8; 011 -64; 100 -256; 101 -1024
#define  COUNTER1_ON  TCCR1B=0b00000011
// счетчик Т0 задает ширину управляющего импульса для серво РВ0 и РВ1
#define  COUNTER0_OFF TCCR0B=0b00000000 // CS02 CS01 CS00 - 000 - отключен; 001  без делителя; 010 c делителем 8; 011 -64; 100 -256; 101 -1024
#define  COUNTER0_ON  TCCR0B=0b00000100
// счетчик Т2 задает ширину управляющего импульса для серво РB2(PD6) и РВ3(PD7)
#define  COUNTER2_OFF TCCR2B=0b00000000 // CS02 CS01 CS00 - 000 - отключен; 001  без делителя; 010 c делителем 8; 011 -64; 100 -256; 101 -1024
#define  COUNTER2_ON  TCCR2B=0b00000110


volatile uint16_t period_20ms;
volatile uint8_t State_of_keyboard;
volatile uint8_t  start_position [6];
volatile int8_t number_servo;


ISR(USART_RX_vect)// прерывание для UART
{
	
	State_of_keyboard=UDR0;
	
	return;
}





ISR(TIMER0_COMPA_vect)// серво РВ0 ширина управляющего импульса
{
	
	PORTB &=~(1<<0);
	TIMSK0&=~(1<<OCIE0A);
	TIFR0 |=(1<<OCF0A);
	
	return;
}


ISR(TIMER0_COMPB_vect)  // серво РВ1 ширина управляющего импульса
{
	PORTB &=~(1<<1);
	TIFR0 |=(1<<OCF0B);
	TIMSK0 &=~(1<<OCIE0B);
	
	return;
}


ISR(TIMER2_COMPA_vect)// серво РВ2(PD6) ширина управляющего импульса
{
	PORTD &=~(1<<6);
	TIFR2 |=(1<<OCF2A);
	TIMSK2 &=~(1<<OCIE2A);
	
	return;
}

ISR(TIMER2_COMPB_vect)// серво РВ3(PD7) ширина управляющего импульса
{
	PORTD &=~(1<<7);
	TIFR2 |=(1<<OCF2B);
	TIMSK2 &=~(1<<OCIE2B);
	
	return;
}



ISR(TIMER1_OVF_vect){// формируем период 20 мс и обновляем регистры счетчики
	
	COUNTER1_OFF;
	COUNTER0_OFF;
	COUNTER2_OFF;
	
	TIFR0 |=(1<<OCF0A);
	TIFR0 |=(1<<OCF0B);
	TIFR2 |=(1<<OCF2A);
	TIFR2 |=(1<<OCF2B);
	
	TIFR1 |=(1<<TOV1);
	PORTB |=(1<<0)|(1<<1);
	PORTD |=(1<<6)|(1<<7);
	TCNT1 = period_20ms; // период 20 мс
	TCNT0 = 0;
	TCNT2 = 0;
	
	TIMSK0|=(1<<OCIE0A)|(1<<OCIE0B);
	TIMSK2|=(1<<OCIE2A)|(1<<OCIE2B);
		
	OCR0A=start_position[1];// положение 0 сервопривода	0
	OCR0B=start_position[2];// положение 0 сервопривода	1
	OCR2A=start_position[3];// положение 0 сервопривода	2
	OCR2B=start_position[4];// положение 0 сервопривода	3
	
	COUNTER1_ON;
	COUNTER2_ON;
	COUNTER0_ON;

	return;
}






void time_delay(long i)
{	cli();sei();
	long k;
	i*=2000;
	for(k=0;k<i;k  ){;;};
	
	
}



void timer_counter0_1_2_INIT()// инициализация таймеров 0,1,2

{
	

	//таймер Т1
	TCCR1A &=~(1<<COM1A0)|~(1<<COM1A1)|~(1<<COM1B0)|~(1<<COM1B1);//внешние выводы отключены
	TCCR1A &=~(1<<WGM10)|~(1<<WGM11);
	TCCR1B &=~(1<<WGM12)|~(1<<WGM13);// режим простого счёта
	period_20ms=60575;
	TCNT1 = period_20ms;
	TIMSK1|=(1<<TOIE1);//|разрешаем прерывания по переполнению
	//TIFR0  флаги переполнения  TOV0
	
	
	//таймер Т0
	TCCR0A &=~(1<<COM0A0)|~(1<<COM0A1)|~(1<<COM0B0)|~(1<<COM0B1);//внешние выводы отключены
	TCCR0A &=~(1<<WGM00)|~(1<<WGM01);
	TCCR0B &=~(1<<WGM02);// режим простого счёта
	
	
	
	//таймер Т2
	TCCR2A &=~(1<<COM2A0)|~(1<<COM2A1)|~(1<<COM2B0)|~(1<<COM2B1);//внешние выводы отключены
	TCCR2A &=~(1<<WGM20)|~(1<<WGM21);
	TCCR2B &=~(1<<WGM22);// режим простого счёта
	
	COUNTER1_ON;
	

}

void servo_reset()
{
	
	
	
	start_position[1]=97;// положение 0 сервопривода	0
	start_position[2]=70;// положение 0 сервопривода	1
	start_position[3]=92;// положение 0 сервопривода	2
	start_position[4]=124; //положение 0 сервопривода	3
	COUNTER1_ON;
	
	
	time_delay(100);
}



void servo_go( int8_t moven, uint8_t servo_position_max, uint8_t servo_position_min)//


{
	
	switch (moven){
		
		case 1:
		start_position[number_servo]  ;
		if(start_position[number_servo]==servo_position_max){start_position[number_servo]--;};// это  90 градусов

		break;
		case 2:
		start_position[number_servo]--;
		if(start_position[number_servo]==servo_position_min){start_position[number_servo]  ;};//6 это -90 градусов
		break;
	};
	
	
	time_delay(20);
	
	return;
	
	
}



//PORTB-0,1, PORTD - 6,7  - управление сервоприводами, 8-битовый счетчик COUNTER 0



int main(void)



{
	uint8_t servo_positionmin=0, servo_positionmax=0;
	int8_t const servo_position1max = 122, servo_position1min=58; //по горизонтали
	int8_t const servo_position2max = 120, servo_position2min=36;//
	int8_t const servo_position3max = 125, servo_position3min=68;//
	int8_t const servo_position4max = 129, servo_position4min=108;// клешня128 108
	
	
	sei();
	DDRD = 0B11000010;	// устанавливаем кнопки D2-D5 на вход, D0 вход RX, D1 выход TX, D6 D7 выходы серво 3 и 4
	PORTD = 0B00111110; // устанавливаем внутренние подтягивающие резисторы
	
	DDRB |=(1<<0)|(1<<1);// устанавливаем выходы порта В для сервоприводов на выход
	PORTB &=(~1<<0)|(~1<<1);
	

	
	UCSR0A=0;//инициализируем UART 
	UCSR0B=0b10010000;
	UCSR0C=0b00000110;
		
	UBRR0L=103;// НА 115200
	UBRR0H=0;
	
	
	timer_counter0_1_2_INIT();
	
	servo_reset();
	PORTB |=(1<<5);
		
	
	while (1)	{

		
		switch (State_of_keyboard)
		{
			case 1:// выбран серво  1 PD0(PB0)
			number_servo=1;
			servo_positionmin=servo_position1min;
			servo_positionmax=servo_position1max;
			break;
			
			case 2: // выбран серво  1 PD0(PB0)
			number_servo=1;
			servo_positionmin=servo_position1min;
			servo_positionmax=servo_position1max;
			break;
					
			case 5:
			number_servo=2; // выбран серво 2   PD1(PB1)
			servo_positionmin=servo_position2min;
			servo_positionmax=servo_position2max;
			break;
						
			case 6:			
			number_servo=2; // выбран серво 2   PD1(PB1)
			servo_positionmin=servo_position2min;
			servo_positionmax=servo_position2max;
			break;
		
			case 7:
			number_servo=3;// выбран серво 3 PD6
			servo_positionmin=servo_position3min;
			servo_positionmax=servo_position3max;
			break;
			
			case 8:		
			number_servo=3;// выбран серво 3 PD6
			servo_positionmin=servo_position3min;
			servo_positionmax=servo_position3max;
			break;
		
			case 3:
			number_servo=4;	// выбран серво 4   PD7
			servo_positionmin=servo_position4min;
			servo_positionmax=servo_position4max;
			break;//  клешня
			
			case 4:
			number_servo=4;	// выбран серво 4   PD7
			servo_positionmin=servo_position4min;
			servo_positionmax=servo_position4max;
			break;//  клешня
			
		
		// cтранный вид программы только из-за того, что адаптировалась клавиатурная версия всего с 4-мя клавишами
		// то есть сначала мы выбирали номер сервопривода клавишами, а уже затем во второй фазе им управляли
		
			}

		if(State_of_keyboard==1||State_of_keyboard==3||State_of_keyboard==5||State_of_keyboard==7)
			{
			servo_go(1,servo_positionmax,servo_positionmin);//
			}
				
		if(State_of_keyboard==2||State_of_keyboard==4||State_of_keyboard==6||State_of_keyboard==8) // кнопка в другом направлении
			{
			servo_go(2,servo_positionmax,servo_positionmin);//
			}	
			
	    time_delay(20);	
	
	}
	
}

Из текста и комментариев понятно, о чем эта программа. Для вывода ШИМ-сигналов на четыре линии порта ввода/вывода мы используем счетчики T1, T0. Каждый из этих счетчиков может работать на два устройства одновременно, затем мы используем счетчики T0, T2, чтобы выставить период выборки 20 миллисекунд.

Эта программа устанавливает начальные положения сервоприводов, загружая счетные регистры OCR0A, OCR0B, OCR2A, OCR2B. Кроме того, мы вводим константы ограничителей, поскольку нам не всегда требуются повороты на 180 градусов. Кроме того, программа перехватывает прерывание UART (от 1 до 8) и преобразует его в команду для сервопривода в виде прерывания от ESP8266. Поскольку имеется четыре сервопривода, каждый из которых работает в двух направлениях, достаточно целых чисел от одного до восьми. В ответ на выбор числа соответствующие регистры счетчика либо увеличиваются, либо уменьшаются, изменяя рабочий цикл управляющего импульса и соответственно вращая выбранный сервопривод. Однако сервоприводы, которые мы не выбрали, продолжают работать с тем же углом поворота (поскольку содержимое соответствующих регистров не изменилось) и удерживают механическую руку в том же положении.

Теперь нам осталось лишь написать управляющую программу, простите за тавталогию, для управления механической рукой уже непосредственно с компьютера по WI-FI.
Код также написан на JAVA, но немного облагорожен. Появился GUI и возможность редактировать номера портов и сетевой адрес ESP8266.

Как зайти в настройки роутера: как войти в роутер и открыть настройки

Что там происходит понятно из окошка. Текст программы я здесь не привожу (он доступен на Гитхабе ), по следующей причине: примерно 95% его объема это создание окна и обработка сигналов от клавиатуры. Но суть такая же как и у предыдущей программы на JAVA. Создается клиент, только UDP, который в зависимости от нажатой клавиши шлёт число от 1 до 8, по указанному адресу на указанный порт.
Или можете сразу взять исполняемый файл отсюда. Для 64 разрядных машин с виндой. Даже установленной среды JAVA не надо. Все уже упихано в 178 Мбайт.

Мой брат собрал, отладил и подарил ему на юбилей механическую ручку. Может поднимать пластиковые рюмки с водкой из другого города по Skype. Несмотря на то, что до механической руки Говарда Воловица из “Теории большого взрыва” нам еще далеко. “.

В следующей статье (если кому-то интересно) будет продемонстрирована возможность управлять им с помощью сотового телефона, использовать четырехколесную тележку-робот, чтобы катать его и обновлять электрические часы временем, собранным с часовых серверов Интернета. Мы поставим на тележку старый смартфон и будем отправлять с него видео в нейронную сеть с распознаванием образов, а нейронная сеть будет управлять моторами. Я уже схожу с ума.

И все это с помощью прекрасной ESP8266.
Буду рад, если кому статья показалась интересной.

[1] Распиновка и характеристики ESP8266
[2]Подключение ESP8266. Быстрый старт.
[3]Обновление прошивки NodeMCU через облако
[4] NODE MCU PyFlasher
[5] ESPlorer — IDE для ESP8266
[6]Программирование на С для AVR
[7]Обзор статей — «Программирование микроконтроллеров на языке Си»
[8]Описание NodeMCU API
[9]Lua Справочник
[10]Lua скрипты и модули
[11]IntelliJ IDEA
[12] Загрузите Java на свой настольный компьютер сейчас!
[13]Atmel Studio

Установка и подключение реле sonoff

Для установки реле Sonoff требуется напряжение 220 Вольт (В). Поэтому его можно легко установить в удобном месте, например, в чаше люстры или непосредственно под подвесным потолком, или в распределительной коробке, если достаточно места.

Отверстие для монтажа на поверхности позволяет прикрепить к ней реле.

Схема проводки реле Sonoff очень проста.

На стороне (вход-вход) подключите питающие фазу и ноль к клеммам (L) и (N). При подключении жил не забывайте о цветовой маркировке.

Размер проводов не должен превышать 1,5 кв. мм. Я же соединил провода сечением 2,5 кв. мм. Таким образом, жесткий провод (однопроволочный) еще можно соединить без труда, а вот гибкий провод (многопроволочный) с гильзовым наконечником НШВИ уже вставлялся с некоторым трудом. Мне даже пришлось его немного сплющить и деформировать.

В примере используется силовой кабель ПВС сечением 2,5 мм2. На другом конце кабеля находится вилка, которую я вставляю в любую розетку 220 В.

На стороне (выход-выход) имеются клеммы (L) и (N), соответствующие фазе и 0 нагрузки.

Я подключил розетку на выходе реле, чтобы было проще подключить нагрузку.

Кроме того, клеммные крышки служат как защитными устройствами, так и зажимами для электропитания.

Вот так все красиво и аккуратно. Реле Sonoff подключено.

В качестве нагрузки я подключил светодиодную лампу, устройство которой я подробно описал в одной из своих статей.

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

Кроме того, в качестве нагрузки не обязательно использовать лампу или группу ламп. При условии, что нагрузка не превышает номинальный ток 10 (А), вы можете без опаски подключать к выходным клеммам любую другую нагрузку. Если необходимо управлять нагрузкой с током более 10 ампер, вы можете подключить ее к контактору и использовать реле для управления катушкой контактора.

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

Как правило, он выглядит примерно так.

Благодаря этому реле sonoff имеет широкий спектр применения. Оно позволяет управлять одной лампочкой, мощным однофазным электронагревателем, трехфазным электродвигателем и т.д. В зависимости от ваших нужд и потребностей.

Теперь мы рассмотрим особенности управления реле Ronoff более подробно.


Мне нет необходимости вскрывать реле и исследовать его конструкцию, информации на эту тему в Интернете достаточно – достаточно заглянуть на соответствующие сайты по электронике. Судя по отзывам, характеристики реле выглядят вполне достойно. Кстати, реле питается от известного китайского микроконтроллера ESP8266.

Смотрите про коптеры:  pump in the boat for water pumping на АлиЭкспресс — купить онлайн по выгодной цене
Оцените статью
Радиокоптер.ру
Добавить комментарий