FDM 3D принтеры стали популярными ЧПУ станками для изготовления прототипов а также даже производства настоящих полнофункциональных изделий и деталей в основном из пластмассы. Чаще всего 3D принтеры делают детали из PLA или ABS пластиков которые весьма дорогие (на момент написания данной стати) в состоянии прутка пригодного для FDM 3D принтера. Большинство FDM 3D принтеров легко переделать в лазерный гравер путем замены экструдера пластика на лазер. Для лазера (в отличии от например фрезера) не нужна жесткая конструкция + 3D принтер может менять фокусировку лазера в процессе работы, чего не могут даже некоторые лазерные граверы. Чтобы переделать 3D принтер в лазерный гравер нужно заменить хотенд принтера на лазерный модуль. Лазерные модули бывают разные. Лазеры бывают разных типов и мощностей. Самые дешёвые, компактые и легкие - это полупроводниковые лазеры они также уступают по мощности например CO2 лазерам но зато + к меньшим габаритам они имеют меньшую стоимость и могут быть установлены на дельта 3D принтеры типа Rostock mini. Обычно дельта на дельта принтеры не устанавливаются тяжелые головки но практика показала лазерный модуль оптической мощностью 5Вт (потребляемая мощность 40Вт) способный резать фанеру и пластик а также гравировать большинство материалов может работать с принтером Rostock mini.
Данный лазерный модуль имеет радиатор, вентилятор для охлаждения и одновременно сдувания дыма от разрезаемой поверхности для улучшения прохождения лазера до этой самой поверхности а также есть сопло которое направляет поток воздуха в разрезаемую точку чтобы лучше сдувать дым. Также есть защитная красная насадка для защиты глаз (на которую не стоит сильно полагаться) и плата управления с тремя выводами. Один вывод питания +12В, второй - земля GND 0В и вывод управления на который подается ШИМ с уровнями напряжения 0В и +5В. В комплекте шел кабель с разъемами. В кабеле 3 провода: красный +12В питания, черный 0В, желтый - ШИМ 0...+5В. Питание подключается к источнику от которого питается принтер. А желтый провод к одному из пинов контроллера RAMPS но только не к тому с которого выходит 12В например стола или вентилятора т.к. эти пины сожгут испортят плату. Нужен именно управляющий пин. Это может быть например свободный пин D4суббота, 10 февраля 2024 г.
Переделка дальта 3D принтера в лазерный ЧПУ гравер
среда, 12 августа 2020 г.
Прием по uart на ассемблере для ATtiny2313
Интерфейс uart (универсальный асинхронный приемник передатчик) часто используется для связи разных устройств друг с другом. Например для связи компьютера с микроконтроллером или микроконтроллера с например радиомодулем или другим микроконтроллером, модулем или микросхемой. Изучив uart микроконтроллера ATtiny2313 можно будет заменить Ардуино, в некоторых случаях, этим микроконтроллером. Чтобы изучить uart можно например поставить какую нибудь задачу например зажечь светодиод подключенный к микроконтроллеру передав ему какой либо код по uartу тогда в процессе решения этой задачи придет понимание того как использовать этот интерфейс. Светодиод, в таком случае, нельзя подключить к нулевому или первому пину порта D т.к. эти пины являются пинами uartа микроконтроллера ATtiny2313. Его можно подключить например к нулевому пину порта B
В схему добавлены разъемы для того чтобы микроконтроллер можно было соединить с программатором чтобы зампрограммировать а потом отсоединить от программатора и соединить с usb-uart переходником для передачи информации на микроконтроллер от компьютера. Кварцевого резонатора в схеме нет. Практика показала что uart может работать и без него. uart - это асинхронный интерфейс т.е. передатчик передает биты через какие то определенные промежутки времени а приемник должен принимать биты через промежутки времени такие же. Иначе приемник будет принимать не то что нужно. К счастью некотарая доля синхронности в этом интерфейсе есть т.к. запускается прием только после возникновения запускающего импульса и асинхронность присутствует только в течении приема одного байта информации (если uart настроен на один байт т.е. 8 бит). Поэтому uart может работать при некотором небольшом несовпадении частот. Чем меньше скорость передачи тем больше может быть это несовпадение. Чтобы это несовпадение было почти нулевым и микроконтроллер мог работать по uartу на очень больших скоростях и очень стабильно и наверняка надежно, нужны специальные кварцевые резонаторы, например не на 1 или 2 МГц а на 1.8432 МГц для того чтобы время тактового импульса было кратным времени одного импульса по стандартам для uart. Естественно uart будет работать и при обычных кварцевых резонаторах (на Ардуине же он как то работает при кварцевых резонаторах с резонансной частотой 16 МГц). В данном случае для простоты мы не будем использовать такие редкие кварцевые резонаторы а используем внутренний rc генератор микроконтроллера с установленной по умолчанию на заводе частотой 1 МГц. Практика показала что uart при этом работает а также при такой частоте микроконтроллер может работать и при пониженном напряжении что позволяет его использовать например при питании от одной ячейки LiFePO4 аккумулятора что удобно для изготовления каких нибудь маленьких радиоуправляемых игрушек или роботов. Рассмотрим ассемблерный код программы:
Первые 4 команды а также инициализация стека, настройка пина на выход были рассмотрены в предыдущих уроках. Адрес ячейки памяти на которую переводиться выполнение программы после того как сработало прерывание по приему байта называется URXCaddr. После того как это прерывание возникло команда RJMP переводит выполнение программы на подпрограмму обработки прерывания. Но чтобы это смогло произойти сначала нужно настроить uart микроконтроллера для этого (а точнее для нашей текущей задачи) есть 5 регистров. Причем в данном случае 2 из них можно даже не трогать. Для начала можно настроить скорость. Слишком большую выбирать нельзя чтобы uart нормально работал. Можно выбрать например 9600 - эта скорость часто используется и подходит во многих случаях. Настраивается скорость через регистры UBRRL и UBRRH. В эти регистры нужно записать число соответствующее нужной нам скорости. Если это число больше 255 то надо младшие разряды этого числа записать в регистр UBRRL а старшие в UBRRH. Если меньше то можно это число записать в UBRRL а UBRRH не трогать вообще т.к. там нули по умолчанию. Чтобы определить это число не обязательно его рассчитывать по формулам. Можно просто найти его из таблицы в документации на микроконтроллер:
Также из этой таблицы видно что в нашем случае можно получить меньшую ошибку если установить бит удвоения скорости в единицу. Находиться этот бит в регистре UCSRA там он под номером 1 (самый первый это нулевой). После того как 3 регистра настроены осталось ещё 2. Разрешить прием байта и прерывание по завершению приема можно настройкой UCSRB. Чтобы разрешить прием, в единицу устанавливается бит 4 этого регистра, чтобы разрешить прерывание по приему, в единицу устанавливается бит 7 этого регистра. Последний регистр UCSRC надо настроить так чтобы принимать по 8 бит. Обычно так всегда и делается но в некоторых случая можно сделать по другому. Чтобы настроить прием 8ми бит нужно в записать единицы в бит 1 и бит 2 регистра UCSRC. Хотя этого можно было бы и не делать т.к. там по умолчанию и так имеются единицы:
Но зато теперь если вдруг понадобиться изменить количество принимаемых бит известно как это сделать. Далее в программе настраивается пин к которому подключен светодиод и разрешаются все прерывания. В основном цикле опять ничего интересного (хотя можно его заполнить например динамической индикацией или ещё чем нибудь). Когда бит приходит по uartу и возникает прерывание нужно вытащить из регистра UDR этот бит и поместить в какой либо регистр общего назначения например R18. Далее командой сравнения CPI и командой условного перехода если не равно BRNE сделать ветвление и организовать зажигание светодиода когда пришел ASCII код символа "a" и гашение светодиода когда пришел ASCII код символа "b". ASCII коды всех символов можно узнать из таблицы ASCII кодов всех символов:
Команда RETI делает выход из подпрограммы обработки прерывания. О том как откомпилировать программы и загрузить её в микроконтроллер можно узнать из предыдущих уроков. Если компиляция и загрузка прошли успешно то можно подключить микроконтроллер к компьютеру через usb-uart переходник и попробовать зажечь светодиод. Отправить какой либо символ с компьютера через переходник можно используя например Arduino IDE или же это можно сделать через командную строку. Если на компьютере обычная ОС Winows напр. 7 то например командой
mode COM3 BAUD=9600 PARITY=n DATA=8
Можно настроить этот переходник на нужную скорость и количество бит. Вместо COM3 нужно вписать название своего com порта который появляется после втыкания переходника в usb разъем. Отправить символ а можно командой
echo a > COM3
символ b соответственно командой
echo b > COM3
Вместо COM3 нужно вписать название своего com порта который появляется после втыкания переходника в usb разъем. После написания команды надо нажимать Enter чтобы символ отправился. В моем случае всё сработало, можно убедиться в этом посмотрев видео:
воскресенье, 5 ноября 2017 г.
3D сканер пространства ультразвуковой на ардуино своими руками
Ардуино имеет небольшую встроенную память для хранения информации поэтому целесообразно передавать отсканированные расстояния сразу на компьютер. Скетчь:
Скачать скетч можно по ссылке https://yadi.sk/d/-Ulj_ggR3PRjje
Для того чтобы использовать данный скетч нужно сначала подключить библиотеку new ping, о том как это сделать можно посмотреть на странице http://electe.blogspot.ru/2015/07/arduino.html
Программа для вывода графики:
КАРТА БЛОГА (содержание)
суббота, 12 августа 2017 г.
ЧПУ пенопласторез
Про источник питания для нихромовой проволоки на странице: http://electe.blogspot.com/2015/03/top243.html
КАРТА БЛОГА (содержание)
воскресенье, 18 сентября 2016 г.
Как печатать на 3D принтере.
По аналогии с данным простым примером G-кодами можно создавать и более сложные изделия. Также знание G кодов будет полезно для настройки 3D принтера.
Видео для данной статьи:
Пластиковые детали для были заказаны на странице http://ali.pub/py0zf
линейные подшипники
http://ali.pub/pq6m3
радиальные подшипники
http://ali.pub/uzqx3
шкивы с ремнём
http://ali.pub/hal0p
http://ali.pub/mcfve (докуплено немного ремня)
хотэнд
http://ali.pub/lhvc3
боуден экструдера (толкатель пластмассы без двигателя)
http://ali.pub/ax7ts
PLA пластик
http://ali.pub/tkpyd
Про источник питания и контроллер смотрите видео:
четверг, 5 мая 2016 г.
USB клавиатура из обычной PS2 (ps/2 to usb converter).
#include "PS2KeyAdvanced.h"
#define DATAPIN 7
#define IRQPIN 3
uint16_t c;
PS2KeyAdvanced keyboard;
byte keys[1000];//convert ps2 to usb hid keyboard
void setup()
{
for(byte i = 0;i<255 i="" p=""> {
keys[i] = 0;
}
keyboard.begin( DATAPIN, IRQPIN );
Serial.begin( 9600 );
//2ps to usb hid
keys[65]=0x4;//A
keys[66]=0x5;//B
keys[67]=0x6;//C
keys[68]=0x7;//D
keys[69]=0x8;//E
keys[70]=0x9;//F
keys[71]=0xa;//G
keys[72]=0xb;//H
keys[73]=0xc;//I
keys[74]=0xd;//J
keys[75]=0xe;//K
keys[76]=0xf;//L
keys[77]=0x10;//M
keys[78]=0x11;//N
keys[79]=0x12;//O
keys[80]=0x13;//P
keys[81]=0x14;//Q
keys[82]=0x15;//R
keys[83]=0x16;//S
keys[84]=0x17;//T
keys[85]=0x18;//U
keys[86]=0x19;//V
keys[87]=0x1a;//W
keys[88]=0x1b;//X
keys[89]=0x1c;//Y
keys[90]=0x1d;//Z
keys[49]=0x1e;//1 !
keys[50]=0x1f;//2 @
keys[51]=0x20;//3 #
keys[52]=0x21;//4 $
keys[53]=0x22;//5 %
keys[54]=0x23;//6 ^
keys[55]=0x24;//7 &
keys[56]=0x25;//8 *
keys[57]=0x26;//9 (
keys[48]=0x27;//0 )
keys[0x1e]=0x28;//Enter
keys[0x1b]=0x29;//Escape
keys[0x1c]=0x2a;//BackSpace
keys[0x1d]=0x2b;//Tab
keys[0x1f]=0x2c;//Space
keys[0x16]=0x4f;//Right Arrow
keys[0x15]=0x50;//Left Arrow
keys[0x18]=0x51;//Down Arrow
keys[0x17]=0x52;//Up Arrow
keys[0x9]=0xe4;//Right ctrl
keys[0x8]=0xe0;//Left ctrl
keys[0x7]=0xe5;//Right shift
keys[0x6]=0xe1;//Left shift
keys[0xb]=0xe6;//Right alt
keys[0xa]=0xe2;//Left alt
keys[0x61]=0x3a;//f1
keys[0x62]=0x3b;//f2
keys[0x63]=0x3c;//f3
keys[0x64]=0x3d;//f4
keys[0x65]=0x3e;//f5
keys[0x66]=0x3f;//f6
keys[0x67]=0x40;//f7
keys[0x68]=0x41;//f8
keys[0x69]=0x42;//f9
keys[0x6a]=0x43;//f10
keys[0x6b]=0x44;//f11
keys[0x6c]=0x45;//f12
keys[0x3c]=0x2d;//-_
keys[0x5f]=0x2e;//+=
keys[0x5d]=0x2f;//{[
keys[0x5e]=0x30;//}]
keys[0x5c]=0x31;//|\
keys[0x5b]=0x33;//:;
keys[0x3a]=0x34;//"'
keys[0x3b]=0x36;//<,
keys[0x3d]=0x37;//>.
keys[0x3e]=0x38;//?/
keys[0x4]=0x46;//Print Screen
keys[0x40]=0x35;//`ё
keys[0x19]=0x49;//insert
keys[0x11]=0x4a;//Home
keys[0x13]=0x4b;//Page Up
keys[0x1a]=0x4c;//Delete
keys[0x12]=0x4d;//End
keys[0x14]=0x4e;//Page Down
keys[0x3]=0x39;//Caps Lock
keys[0x2]=0x41;//Scroll Lock
keys[0x1]=0x41;//Num Lock
}
void loop()
{
if( keyboard.available() )
{
c = keyboard.read();
if( ((c >> 8) != 0x81) && ((c >> 8) != 0x80) && ((c >> 8) != 0xc0) && ((c >> 8) != 0x90) && ((c >> 8) != 0x91))
{
Serial.write(keys[c & 0xFF]);
}
}
}255>
Скетч получился довольно длинный т.к. для преобразования кодов клавиш с клавиатуры в коды для отправки по USB используется массив "keys". Это обычный массив который используется необычным способом а точнее как ассоциативный массив и из за этого он избыточен и занимает много места в и без того забитой памяти микроконтроллера но зато дальше можно написать только одну строку не длинного текста для преобразования кодов что очень удобно. В условии в основном цикле проверяется "не отпущена ли кнопка". В данный массив записаны не все коды клавиш, в скетче много "магических чисел" и вообще он далеко не идеален и клавиатура в конце концов не сможет делать всё что могла бы обычная usb клавиатура но данный скетч в открытом доступе и его может исправить и дополнить любой желающий который также может выложить свой скетч в открытый доступ поэтому давайте перейдём с следующему скетчу:
#include "UsbKeyboard.h"
void setup() {
Serial.begin(9600);
TIMSK &= !(1
usbDeviceDisconnect();
delayMs(250);
usbDeviceConnect();
sei();
}
void loop()
{
UsbKeyboard.update();
if (Serial.available() > 0)
{
UsbKeyboard.sendKeyStroke(Serial.read());
}
}
// helper method for V-USB library
void delayMs(unsigned int ms)
{
for( int i=0; i
delayMicroseconds(1000);
}
}
Этот скетч короче но совсем не проще. В главной функции настройка прерываний и всего остального, в основном цикле обязательная функция UsbKeyboard.update() которая должна вызываться не реже чем 20 раз в секунду (иначе всё работать не будет), поэтому микроконтроллер с v-usb сильно грузить не рекомендуется но, к счастью для нас (и для этого микроконтроллера), другую серьёзную задачу выполняет другой микроконтроллер который находится в другой Ардуине. После того как по UARTу принимается байт он сразу же отправляется по USB в компьютер и всё это происходит быстрее чем за 50мс судя по тому что всё работает (см. видео ниже). Т.к. данная библиотека реализует класс HID то на компьютер к которому будет подключён данный адаптер с клавиатурой не надо устанавливать никаких драйверов всё должно заработать и на Windows и на Linux. Я же делал данный переходник (адаптер) для Raspberry pi 3 с операционной системой Raspbain и клавиатура с ними работала замечательно (см. видео ниже), с Windows 7 были некоторые проблемы т.к. она решила что нужен драйвер к неизвестному устройству, решила его найти и установить но после того как не получилось вывелось сообщение об этом и дальше клавиатурой можно было спокойно пользоваться. Теперь можно посмотреть видео с испытаниями и некоторой другой полезной информацией:
Второй (usb hid) по ссылке https://yadi.sk/d/b5mNkEIarWkXn
КАРТА БЛОГА (содержание)
Arduino UNO можно заказать по ссылке http://ali.pub/1v22bh, Atmega8-pu которую (можно превратить в Arduino) по ссылке http://ali.pub/qgw75, Raspberry Pi 3 (на котором испытывалась клавиатура в видео) по ссылке http://ali.pub/91xb2.
четверг, 6 августа 2015 г.
Простое управление приборами с компьютера.
Это нестандартная схема для лучшего понимания, обычно используют схемы такие:
Хотя в этой схеме тоже присутствует нестандартное обозначение платы Ардуино. На рисунке обозначено Arduino UNO (можно заказать по этой ссылке http://ali.pub/1v22bh) но можно использовать и любое другое. Соединения можно делать например на макетной плате и проводами или пайкой. После того как всё правильно соединено и проверено можно подключить Ардуино по USB к компьютеру и загрузить в неё скетч:
char pc_code=0;
void setup()
{
pinMode(2, OUTPUT);
Serial.begin(9600);
}
void loop()
{
if (Serial.available() > 0)
{
pc_code = Serial.read();
if(pc_code=='a')
{
digitalWrite(2, HIGH);
}
else if(pc_code=='b')
{
digitalWrite(2, LOW);
}
}
}
О том как правильно настроить Ардуино и загрузить в неё скетч уже описано на странице "Простое управление шаговым двигателем с компьютера через ардуино". Далее для включения прибора необходимо на Ардуино отослать символ "a" для выключения символ "b". Для того чтобы отослать символ на ардуино можно, в среде Arduino IDE, войти по вкладке Инструменты-Монитор последовательного порта и в появившемся окне в верхнем текстовом поле вписывать символы и отсылать нажатием кнопки "отправить" символ придёт на ардуино и для данного случая если отослать символ "a" то прибор включиться, если "b" то соответственно выключиться. Если Ардуино не принимает символы то нужно в правом нижнем углу окна монитора последовательного порта установить такую же скорость какая прописана в скетче т.е. 9600 бод. Для того чтобы включать 2 прибора можно немного изменить скетч:
char pc_code=0;
void setup()
{
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
Serial.begin(9600);
}
void loop()
{
if (Serial.available() > 0)
{
pc_code = Serial.read();
if(pc_code=='a')
{
digitalWrite(2, HIGH);
}
else if(pc_code=='b')
{
digitalWrite(2, LOW);
}
else if(pc_code=='c')
{
digitalWrite(3, HIGH);
}
else if(pc_code=='d')
{
digitalWrite(3, LOW);
}
}
}
КАРТА БЛОГА (содержание)
пятница, 1 мая 2015 г.
Простое управление шаговым двигателем с компьютера через ардуино.
воскресенье, 12 октября 2014 г.
Ввод через usb.
Включение светодиода через usb.
usb светофор.
Управление шаговыми двигателями через USB порт.
В этой статье рассмотрим пример передачи информации от микроконтроллера компьютеру через USB порт. Для передачи состояния кнопки можно использовать схему:
Полный текст программы для микроконтроллера приведен в статье управление шаговыми двигателями через USB порт. Рассмотрим участок кода для передачи информации на компьютер:
if(rq->bRequest == CUSTOM_RQ_GET_STATUS){
static uchar dataBuffer[1]; /* buffer must stay valid when usbFunctionSetup returns */
//отослать состояние 3го бита порта D
if(!(PIND & (1<
dataBuffer[0] = 0;
}
else
{
dataBuffer[0] = 1;
}
usbMsgPtr = dataBuffer; /* tell the driver which data to return */
return 1; /* tell the driver to send 1 byte */
}
Код может быть не понятен но нетрудно догадаться что передаваемый байт записывается в переменную usbMsgPtr. Из строки:
if(rq->bRequest == CUSTOM_RQ_GET_STATUS)
понятно что для передачи информации на ПК на микроконтроллер с этого ПК приходит запрос:
CUSTOM_RQ_GET_STATUS
Рассмотрим теперь код для ПК:
#include 〈windows.h〉
#include 〈stdio.h〉
#include 〈stdlib.h〉
#include 〈usb.h〉 /* this is libusb */
#include 〈stdbool.h〉 //булева библиотека
#include 〈GL/gl.h〉
#include 〈GL/glext.h〉
#include 〈GL/glu.h〉
#include "opendevice.h" /* common code moved to separate module */
#include "../firmware/requests.h" /* custom request numbers */
#include "../firmware/usbconfig.h" /* device's VID/PID and names */
#define USB_CFG_VENDOR_NAME 'e','l','e','c','t','e','.','b','l','o','g','s','p','o','t','.','c','o','m'
#define USB_CFG_VENDOR_NAME_LEN 19
#define USB_CFG_DEVICE_NAME 'm','y','u','s','b','d','e','v','i','c','e'
#define USB_CFG_DEVICE_NAME_LEN 11
#define NUMBER_TRANGLE 30
int i=0;
int j=0;
HDC hdc;
HGLRC hrc;
usb_dev_handle *handle = NULL;
const unsigned char rawVid[2] = {USB_CFG_VENDOR_ID}, rawPid[2] = {USB_CFG_DEVICE_ID};
char vendor[] = {USB_CFG_VENDOR_NAME, 0}, product[] = {USB_CFG_DEVICE_NAME, 0};
char buffer[4];
int vid, pid;
// Enable OpenGL
void EnableOpenGL( HWND hWnd, HDC * hDC, HGLRC * hRC )
{
PIXELFORMATDESCRIPTOR pfd;
int iFormat;
// get the device context (DC)
*hDC = GetDC( hWnd );
// set the pixel format for the DC
ZeroMemory( &pfd, sizeof( pfd ) );
pfd.nSize = sizeof( pfd );
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 16;
pfd.iLayerType = PFD_MAIN_PLANE;
iFormat = ChoosePixelFormat( *hDC, &pfd );
SetPixelFormat( *hDC, iFormat, &pfd );
// create and enable the render context (RC)
*hRC = wglCreateContext( *hDC );
wglMakeCurrent( *hDC, *hRC );
}
// Disable OpenGL
void DisableOpenGL( HWND hWnd, HDC hDC, HGLRC hRC )
{
wglMakeCurrent( NULL, NULL );
wglDeleteContext( hRC );
ReleaseDC( hWnd, hDC );
}
/* Declare Windows procedure */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
/* Make the class name into a global variable */
char szClassName[ ] = "WindowsApp";
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nFunsterStil)
{
BOOL bQuit = FALSE;
float coords_trangles[NUMBER_TRANGLE];
float dcoords_trangles[NUMBER_TRANGLE];
float angles_trangles[NUMBER_TRANGLE];
float dangles_trangles[NUMBER_TRANGLE];
for (i=0;i〈NUMBER_TRANGLE;i++)
{
coords_trangles[i]=0;
dcoords_trangles[i]=0;
angles_trangles[i]=0;
dangles_trangles[i]=0;
}
HWND hwnd; /* This is the handle for our window */
MSG messages; /* Here messages to the application are saved */
WNDCLASSEX wincl; /* Data structure for the windowclass */
/* The Window structure */
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */
wincl.style = CS_DBLCLKS; /* Catch double-clicks */
wincl.cbSize = sizeof (WNDCLASSEX);
/* Use default icon and mouse-pointer */
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL; /* No menu */
wincl.cbClsExtra = 0; /* No extra bytes after the window class */
wincl.cbWndExtra = 0; /* structure or the window instance */
/* Use Windows's default color as the background of the window */
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
/* Register the window class, and if it fails quit the program */
if (!RegisterClassEx (&wincl))
return 0;
/* The class is registered, let's create the program*/
hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */
szClassName, /* Classname */
"Windows App", /* Title Text */
WS_OVERLAPPEDWINDOW, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
800, /* The programs width */
600, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* No menu */
hThisInstance, /* Program Instance handler */
NULL /* No Window Creation data */
);
usb_init();
// compute VID/PID from usbconfig.h so that there is a central source of information
vid = rawVid[1] * 256 + rawVid[0];
pid = rawPid[1] * 256 + rawPid[0];
if(usbOpenDevice(&handle, vid, vendor, pid, product, NULL, NULL, NULL) != 0){
MessageBox(hwnd, "Could not find USB device\n","error", 0);
exit(1);
}
else
{
MessageBox(hwnd, "Find USB device done!\n","Done!", 0);
}
ShowWindow (hwnd, nFunsterStil);
EnableOpenGL( hwnd, &hdc, &hrc );
while (!bQuit)
{
if (PeekMessage(&messages, NULL, 0, 0, PM_REMOVE))
{
// handle or dispatch messages
if (messages.message == WM_QUIT)
{
bQuit = TRUE;
}
else
{
TranslateMessage(&messages);
DispatchMessage(&messages);
}
}
else
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CUSTOM_RQ_GET_STATUS,0,0, buffer, sizeof(buffer), 5000);
if(buffer[0]==0)
{
SetWindowText(hwnd, "Button on");
}
else
{
SetWindowText(hwnd, "Button off");
}
for(i=0;i〈NUMBER_TRANGLE/3;i++)
{
if(buffer[0]==0)
{
coords_trangles[i*3]=0.0f;
coords_trangles[i*3+1]=0.0f;
coords_trangles[i*3+2]=0.0f;
dcoords_trangles[i*3]=((float)rand())/(100*(float) RAND_MAX)-((float)rand())/(100*(float) RAND_MAX);
dcoords_trangles[i*3+1]=((float)rand())/(100*(float) RAND_MAX)-((float)rand())/(100*(float) RAND_MAX);
dangles_trangles[i*3+2]=((float)rand())/((float) RAND_MAX)-((float)rand())/((float) RAND_MAX);
}
glPushMatrix();
glTranslatef(coords_trangles[i*3],coords_trangles[i*3+1],coords_trangles[i*3+2]);
glRotatef(angles_trangles[i*3+2], 0.0f, 0.0f, 1.0f);
glBegin(GL_TRIANGLES);
glColor3f( 1.0f, 0.0f, 0.0f ); glVertex2f( 0.0f, 0.20f );
glColor3f( 0.0f, 1.0f, 0.0f ); glVertex2f( 0.287f, -0.25f );
glColor3f( 0.0f, 0.0f, 1.0f ); glVertex2f( -0.287f, -0.25f );
glEnd();
glPopMatrix();
coords_trangles[i*3]+=dcoords_trangles[i*3];
coords_trangles[i*3+1]+=dcoords_trangles[i*3+1];
coords_trangles[i*3+2]+=dcoords_trangles[i*3+2];
angles_trangles[i*3+2]+=dangles_trangles[i*3+2];
dcoords_trangles[i*3]*=0.9965f;
dcoords_trangles[i*3+1]*=0.9965f;
}
SwapBuffers( hdc );
}
}
usb_close(handle);
DisableOpenGL( hwnd, hdc, hrc );
return messages.wParam;
}
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
PostQuitMessage (0);
break;
default:
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}
Приём байта осуществляет функция:
usb_control_msg
Рассмотрим пример использования этой функции для передачи:
usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, CUSTOM_RQ_SET_STATUS, out_conditions[dt_count], 0, buffer, sizeof(buffer), 5000);
Четвёртым параметром является передаваемая информация, шестым-буфер для приёма информации, седьмым- размер этого буфера.
Для приёма информации нужно изменить второй и третий параметры:
usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CUSTOM_RQ_GET_STATUS,0,0, buffer, sizeof(buffer), 5000);
Для того чтобы использовать OpenGL пришлось внести изменения в Makefile.
строку:
USBLIBS = -L"c:/Program Files/LibUSB-Win32/lib/gcc" -lusb
заменить на (т.е. немного дописать):
USBLIBS = -L"c:/Program Files/LibUSB-Win32/lib/gcc" -lusb -lopengl32 -lglu32 -mwindows
и в папку
c:/Program Files/LibUSB-Win32/lib/gcc
добавить файлы:
libopengl32.a
libglu32.a
Также необходимо добавить заголовочные файлы:
#include 〈GL/gl.h〉
#include 〈GL/glext.h〉
#include 〈GL/glu.h〉
Скачать программу для микроконтроллера можно по ссылке:https://yadi.sk/d/EJJiYBuRbxEXB
Программу для ПК по ссылке:https://yadi.sk/d/ZDdoRYtObxEfe
КАРТА БЛОГА (содержание)
Подходящие микроконтроллеры ATmega8a-pu (можно заказать по ссылке).