1035
把激光投影机提供零部件
UPD:的文件添加到板上DAC GitHub的
我原本打算让<一href="http://ru.wikipedia.org/wiki/%D0%9B%D0%B0%D0%B7%D0%B5%D1%80%D0%BD%D0%B0%D1%8F_%D0%B0%D1%80%D1%84%D0%B0">Лазерную竖琴的,但还没有得到中间结果 - 一个设备,可以用来作为激光投影仪 - 激光绘制记录在文件格式ILDA各个附图。据我所知,许多谁占用的激光投影机的组装,作为一个装置来控制振镜(和不知道如何最好地翻译成俄文混合“振镜扫描仪&QUOT;),采用略作修改廉价声卡的PC。我去一个不同的方式,因为最终我需要完全独立的单元,它无需电脑即可工作。
让我们来看看什么是我的激光投影仪。所有零部件的成本大约为8000卢布,其中一半以上 - 一个70mW的激光模块
<一个href="http://www.ebay.com/itm/20Kpps-HightSpeed-galvo-scanner-max35Kpps-/251501064829?pt=US_Stage_Lighting_Single_Units&hash=item3a8ea1b27d">Гальванометры和司机对他们偏转激光束沿轴X / Y 70mW的532nm的激光模块的供电由5V龙激光SGLM70 德州仪器(TI)的Stellaris快速启动 在自制的卡片与DAC AD7249BRZ 电源< / LI> OL>
硬件 H4>在使用的Stellaris启动板的“大脑”(因为它是速度快,具有USB硬件支持)和12位双通道DAC,串行接口ADI公司的AD7249BRZ 。为了控制束的偏转在输入驱动器必须在-5至5伏的范围内应用的模拟信号。 DAC AD7249BRZ只是能够在此模式下工作(并且也从0到5伏,0到10伏)。对他来说,我在鹰扔了一个特殊的费用,这是连接到的Stellaris启动板。董事会需要双极电源,这是由芯片 ICL7660 的手段获得。为了提供给必要的检流计电源(15V)单路输出电压转换成给我,我用了一个线性稳压器LM317,后来被证明是最好的解决方案,尤其是对激光模块的电源 - 因为LM-KA一个大散热器(在视频中看到的那样) 10分钟后工作被加热到70度不带散热片,它只是非常迅速过热和断开过热(与它的激光模块,这也是我最初决定它烧毁,几乎推迟了几个砖,因为当咸鱼翻身它不包括 - 因为它已经变成了这么长时间,直到凉爽的芯片)
与文件修改后的激光器模块 H6>原理图和PCB AD7249BRZ介绍如下。也许细心的读者会发现,在错误的方案,因为它不知什么原因,在我看来对于不与运算放大器的一部分,其目的是使电路的<一个输出工作href="http://ru.wikipedia.org/wiki/%D0%91%D0%B0%D0%BB%D0%B0%D0%BD%D1%81%D0%BD%D0%BE%D0%B5_%D0%BF%D0%BE%D0%B4%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D0%B5">балансным从干扰更大的保障。我的副本,而不是平衡信号输出的不平衡,但尽管如此,一切工作正常。
软 H4>这似乎对铁的结尾最有趣的事情,所以去的软件。它由两部分组成 - 一个实用程序的PC和固件对于Stellaris启动板,它实现了USB批量单元与每个32位其自己的数据包格式。样品的格式进行说明由以下结构:
未来计划 H4>拟仍然完成这些事情类似原定激光竖琴的状态。为了这个目的只有一个,而不是两个反射镜,由于激光束只沿着一个轴移动。竖琴的操作原理是控制器点燃和熄灭激光束在某些时候它在空气中产生激光“键盘”。艺术家,堵狼狈为奸反射明亮的激光束激活感光元件的“竖琴”的基础。由于微控制器知道在什么时刻其中键盘的一部分,他“画”,可以确定哪个波束的已被封锁。然后,它的到相应的MIDI消息的形成和将其发送到计算机或连接以形成一个硬件合成声音。
我原本打算让<一href="http://ru.wikipedia.org/wiki/%D0%9B%D0%B0%D0%B7%D0%B5%D1%80%D0%BD%D0%B0%D1%8F_%D0%B0%D1%80%D1%84%D0%B0">Лазерную竖琴的,但还没有得到中间结果 - 一个设备,可以用来作为激光投影仪 - 激光绘制记录在文件格式ILDA各个附图。据我所知,许多谁占用的激光投影机的组装,作为一个装置来控制振镜(和不知道如何最好地翻译成俄文混合“振镜扫描仪&QUOT;),采用略作修改廉价声卡的PC。我去一个不同的方式,因为最终我需要完全独立的单元,它无需电脑即可工作。
让我们来看看什么是我的激光投影仪。所有零部件的成本大约为8000卢布,其中一半以上 - 一个70mW的激光模块
<一个href="http://www.ebay.com/itm/20Kpps-HightSpeed-galvo-scanner-max35Kpps-/251501064829?pt=US_Stage_Lighting_Single_Units&hash=item3a8ea1b27d">Гальванометры和司机对他们偏转激光束沿轴X / Y 70mW的532nm的激光模块的供电由5V龙激光SGLM70 德州仪器(TI)的Stellaris快速启动 在自制的卡片与DAC AD7249BRZ 电源< / LI> OL>
硬件 H4>在使用的Stellaris启动板的“大脑”(因为它是速度快,具有USB硬件支持)和12位双通道DAC,串行接口ADI公司的AD7249BRZ 。为了控制束的偏转在输入驱动器必须在-5至5伏的范围内应用的模拟信号。 DAC AD7249BRZ只是能够在此模式下工作(并且也从0到5伏,0到10伏)。对他来说,我在鹰扔了一个特殊的费用,这是连接到的Stellaris启动板。董事会需要双极电源,这是由芯片 ICL7660 的手段获得。为了提供给必要的检流计电源(15V)单路输出电压转换成给我,我用了一个线性稳压器LM317,后来被证明是最好的解决方案,尤其是对激光模块的电源 - 因为LM-KA一个大散热器(在视频中看到的那样) 10分钟后工作被加热到70度不带散热片,它只是非常迅速过热和断开过热(与它的激光模块,这也是我最初决定它烧毁,几乎推迟了几个砖,因为当咸鱼翻身它不包括 - 因为它已经变成了这么长时间,直到凉爽的芯片)
激光模块本身不支持TTL调制,所以,当我厌倦了只是推动激光在不同的方向,我想过,当时间被接通和关断梁。这涉及修改激光器模块烙铁。幸运的是,几乎所有的中国激光模组都非常相似,彼此,操作简单,并在运算放大器LM358制成。焊料在他的脚3和4(非反相输入端和地,分别地)发射极和集电极第一得到双极晶体管2N4401,我从而有机会来调制激光器的操作,将控制信号馈送到晶体管的基:
与文件修改后的激光器模块 H6>原理图和PCB AD7249BRZ介绍如下。也许细心的读者会发现,在错误的方案,因为它不知什么原因,在我看来对于不与运算放大器的一部分,其目的是使电路的<一个输出工作href="http://ru.wikipedia.org/wiki/%D0%91%D0%B0%D0%BB%D0%B0%D0%BD%D1%81%D0%BD%D0%BE%D0%B5_%D0%BF%D0%BE%D0%B4%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D0%B5">балансным从干扰更大的保障。我的副本,而不是平衡信号输出的不平衡,但尽管如此,一切工作正常。
我希望你不害怕的可怕图像从卡中带着淡淡的芯片管脚,这是用酒精擦拭后形成的。顺便说一下,为什么焊剂洗涤建议异丙醇,因为它不会留下残余物,例如其原因。顺便说一句,有趣的是,这种类型的连接器与主板上的闩锁 - 它插头莫仕(22-23-2021插座,插头22-01-3027,08-50-0114联系叉),通过Digikey命令他们,因为中国人,他们在某种程度上猥亵昂贵。
软 H4>这似乎对铁的结尾最有趣的事情,所以去的软件。它由两部分组成 - 一个实用程序的PC和固件对于Stellaris启动板,它实现了USB批量单元与每个32位其自己的数据包格式。样品的格式进行说明由以下结构:
<前>&LT;代码级=&QUOT; CPP&QUOT;&GT; typedef结构{无符号X:12; //坐标x无符号的RX:4; //标志(开启/关闭激光)无符号Y:12; //坐标y无符号RY:4; //未使用} SAMPLE_T; &所述; /代码&GT; 预>该设备使用一个USB缓冲器512字节,其中的PC与一定的余量,并在这样的速率不引起溢出的缓冲器的下溢或写入数据。设计映射20000点每秒用过电流计,所需要的是采样频率。从USB处理速度的数据的功能由陈腐<预类=“prettyprint”> <代码>调节SysCtlDelay 代码> PRE>。通过调节系统的值可以被调整,使得ILDA测试图像正确地显示:
处理20000样本的每个数据包后,在斋闪烁的开头视频的绿色指示灯。也就是说,理想情况下,就应眨眼每秒恰好1次。
PC的软件部分是基于从包 OpenLase <<预先类=“prettyprint”> <代码> playilda.c 代码> PRE> /一>,但切出一切不必要的,而是与服务器JACK使用的libusb将数据包发送到的Stellaris启动板通信。
程序的源代码为PC B> <前>&LT;代码级=&QUOT; CPP&QUOT;&GT;的#include&LT; stdlib.h中&GT; #包括&LT; SYS / time.h中&GT; #包括&LT; time.h中&GT; #包括&LT; stdio.h中&GT; #包括&LT; string.h中&GT; #包括&LT;的libusb-1.0 / libusb.h&GT; #包括&LT;的iostream&GT; #包括&LT;字符串&GT; #包括&LT;载体&GT;的#define MAGIC 0x41444C49静态内嵌uint16_t swapshort(uint16_t v)的{返回(ⅴ&GT;→8)| (V族;&所述; 8); }浮球规模= 1.0; typedef结构{uint32_t的法宝; uint8_t有PAD1 [3]; uint8_t有格式;字符的名称[8];焦炭公司[8]; uint16_t计数; uint16_t frameno; uint16_t framecount; uint8_t有扫描仪; uint8_t有PAD2; } __attribute __((盒装))ilda_hdr; #定义空白0X40的#define最后0x80的typedef结构{int16_t X; int16_tÿ; int16_t Z者除外; uint8_t有状态; uint8_t有颜色; } __attribute __((盒装))icoord3d; typedef结构coord3d {int16_t X; int16_tÿ; int16_t Z者除外; uint8_t有状态; coord3d(int16_t X,int16_t Y,int16_t Z,uint8_t有状态):X(X),Y(Y),Z(Z),州(州){}} coord3d; typedef结构{性病::矢量&lt; coord3d&GT;分; INT位置; }框架;框架rframe; INT SUBPOS; INT分频器= 1; INT loadildahdr(FILE * ILD,ilda_hdr和放大器; HDR){如果(FREAD(安培; HDR,的sizeof(HDR),1,ILD)= 1!){性病:: CERR&LT;&LT; &QUOT;错误,而读头与QUOT; &LT;&LT;的std :: ENDL;返回-1; }如果(hdr.magic =魔法!){性病:: CERR&LT;&LT; &QUOT;无效幻&QUOT; &LT;&LT;的std :: ENDL;返回-1; }如果(hdr.format!= 0){fprintf中(错误,&QUOT;不支持部分类型%D \ñ&QUOT;,hdr.format);返回-1; } Hdr.count = swapshort(hdr.count); hdr.frameno = swapshort(hdr.frameno); hdr.framecount = swapshort(hdr.framecount); }诠释loadild(常量的std ::字符串和放大器;文件,帧放;帧){诠释我; FILE * ILD =的fopen(file.c_str(),&QUOT; RB&QUOT;);如果(ILD!){性病:: CERR&LT;&LT; &QUOT;无法打开&QUOT; &LT;&LT;文件&LT;&LT;的std :: ENDL;返回-1; } Ilda_hdr HDR; loadildahdr(ILD,HDR);对于(INT F = 0; F&LT; hdr.framecount;˚F++){性病::法院&LT;&LT; &QUOT;框架&QUOT; &LT;&LT; hdr.frameno&LT;&LT; &QUOT;的&QUOT; &LT;&LT; hdr.framecount&LT;&LT; &QUOT; &QUOT; &LT;&LT; hdr.count&LT;&LT; &QUOT;点&QUOT; &LT;&LT;的std :: ENDL; icoord3d * TMP =(icoord3d *)释放calloc(hdr.count,的sizeof(icoord3d));如果(FREAD(TMP,的sizeof(icoord3d),hdr.count,ILD)= hdr.count!){性病:: CERR&LT;&LT; &QUOT;错误,而阅读框QUOT; &LT;&LT;的std :: ENDL;返回-1; }对于(i = 0; I&LT; hdr.count;我++){coord3d点(swapshort(TMP [I] .X),swapshort(TMP [I] .Y),swapshort(TMP [I] .Z) TMP [I] .state); frame.points.push_back(点); }免费(TMP); loadildahdr(ILD,HDR); } FCLOSE(ILD);返回0; }短outBuffer [128]; INT过程(){帧*帧=安培; rframe;短* SX =安培; outBuffer [0];短* SY =安培; outBuffer [1];对于(INT FRM = 0; FRM&LT; 64,FRM ++){结构coord3d * C =&功放;框架&GT;点[框架&GT;位置]。 * SX = 4095 - (2047 +(2048 * C - &GT; X / 32768))*规模; * SY =(2047 +(2048 * C - &GT; Y / 32768))*规模;如果(C-→状态和放大器;空白){* SX | = 1&LT;&LT; 15; }其他{* SX&安培; =〜(1&LT;&LT; 15); } + Sx的= 2; SY + = 2; SUBPOS ++;如果(SUBPOS ==分频器){SUBPOS = 0;如果(C-→状态和放大器; LAST)框架&GT;位置= 0;其他框架&GT;位置=(框架&GT;仓位+ 1)%框架&GT; points.size(); }}返回0; }诠释的主要(INT ARGC,字符** argv的){libusb_device_handle * dev的; libusb_context * CTX = NULL; INT RET,实际的; RET = libusb_init(安培; CTX);如果(RET&LT; 0){fprintf中(错误,&QUOT;无法初始化libusb的\ N'QUOT;);返回EXIT_FAILURE; } Libusb_set_debug(CTX,3);开发= libusb_open_device_with_vid_pid(CTX,0x1cbe,为0x0003);如果(DEV == NULL){fprintf中(错误,&QUOT;不能打开设备\ñ&QUOT;);返回EXIT_FAILURE; }其他的printf(&QUOT;设备打开\ñ&QUOT;);如果(libusb_kernel_driver_active(DEV,0)== 1){fprintf中(错误,&QUOT;内核驱动器的有源\ñ&QUOT;); libusb_detach_kernel_driver(dev的,0); }的Ret = libusb_claim_interface(dev的,0);如果(RET&LT; 0){fprintf中(错误,&QUOT;不能要求接口\ñ&QUOT;);返回EXIT_FAILURE; } //为了保持我们的采样率结构的timespec TS; ts.tv_sec = 0; ts.tv_nsec = 2000000; memset的(安培; rframe,0,sizeof的(帧));如果(loadild(的argv [1],rframe)小于0){fprintf中(错误,&QUOT;无法加载ILDA \ñ&QUOT;);返回EXIT_FAILURE; }当(1){处理();如果(了nanosleep(安培; TS,NULL)!= 0)fprintf中(错误,&QUOT;失败了nanosleep&QUOT); RET = libusb_bulk_transfer(DEV,(1 | LIBUSB_ENDPOINT_OUT),(无符号字符*)及outBuffer,256,和放大器;实际,0);如果(RET = 0 ||实际= 256!)fprintf中(错误,&QUOT;写错误。\ n&QUOT;); } Libusb_release_interface(dev的,0); libusb_close(开发); libusb_exit(CTX);返回0; }中尉; /码&GT; PRE>
有
<代码> main()的代码> PRE>使用了nanosleep也通过与新的数据被发送到微控制器的频率支配。提供。
的功能 控制器固件的完整的源代码是在GitHub上