使用SPRESENSE电路板的POV显示器

我使用SPRESENSE和DotStar LED编带制作了全彩POV显示器。
使用SPRESENSE电路板的POV显示器_第1张图片

硬件清单

索尼Spresense主板(主板及扩展件)
QTR-1A反射传感器
DotStar数字LED编带
DFRobot无线充电模块5V / 1A
直流电机RS-540SH
SPRESENSE迷你扩展板
电压电平转换器

软件应用程序和在线服务

Arduino IDE

故事

我使用SPRESENSE、无线充电模块和DotStar LED编带制作了全彩POV(视觉暂留)显示器。

搭建过程

LED胶带、SPRESENSE和反射传感器安装在旋转组件上,并且LED编带采用DotStar。使用无线充电模块执行对旋转部件的无线供电过程。
一节AA电池用于电机供电,三节AA电池用于向旋转部件提供无线电源。

使用SPRESENSE电路板的POV显示器_第2张图片

POV显示设备

电机采用金属配件固定,手柄采用黑色木材制成,电池插座和电源开/关滑动开关固定。

使用SPRESENSE电路板的POV显示器_第3张图片

旋转组件完全独立,如下所示。

使用SPRESENSE电路板的POV显示器_第4张图片
我使用了两个Dotstar LED编带。29芯LED灯带经由SPI4进行控制。28芯LED编导由SPI5进行控制。
使用SPRESENSE电路板的POV显示器_第5张图片

我敷设了一层乳白色的薄膜,用于光的传播。

使用SPRESENSE电路板的POV显示器_第6张图片

电压电平转换器TXB0104用于将SPRESENSE的逻辑电平从1.8V转换为5V。
使用SPRESENSE电路板的POV显示器_第7张图片

我使用无线充电模块为LED旋转组件供电。它只是将传动线圈面向电动机旋转轴,而几乎不需要执行任何操作。

使用SPRESENSE电路板的POV显示器_第8张图片

Arduino IDE代码

以下库用于Dotstar.https://github.com/adafruit/Adafruit_DotStar
Adafruit_DotStar_SPI5.h是对Adafruit_DotStar.h的修改,以便能够使用SPI5。
当反射传感器检测到标记信号时,它会减小输出,因此它会在附加中断中检测到标记信号,并测量中断处理一圈所需的时间。
它通过将一圈的时间除以150使得LED闪烁切换。LED显示模式以阵列形式存储在graphics.h中。

代码

#include 
 
#include "Adafruit_DotStar_SPI5.h"
 
#include 
 
#include "graphics.h"
 
#define NUMPIXELS2 29 // Number of LEDs in strip
 
#define NUMPIXELS 57 // Number of LEDs in 2 strips
 
#define Frame 16
 
#define Div 150
 
#define Fclk 26000000
 
#define itrPin 19
 
int numRot = 0;
 
int numDiv = 0, numDiv2 = 0;
 
int stateDiv = 0;
 
unsigned long rotTime, timeOld, timeNow;
 
Adafruit_DotStar_SPI5 strip5 = Adafruit_DotStar_SPI5(NUMPIXELS2, DOTSTAR_BGR);
 
Adafruit_DotStar strip4 = Adafruit_DotStar(NUMPIXELS2, DOTSTAR_BGR);
 
void setup() {
 
 Serial.begin(115200);
 
 strip5.begin();
 
 SPI5.beginTransaction(SPISettings(Fclk, MSBFIRST, SPI_MODE0));
 
 strip4.begin();
 
 SPI.beginTransaction(SPISettings(Fclk, MSBFIRST, SPI_MODE0));
 
 strip5.clear();
 
 strip4.clear();
 
 strip5.show();
 
 strip4.show();
 
 delay(500);
 
 attachInterrupt(digitalPinToInterrupt(itrPin), RotCount, FALLING );
 
}
 
void loop() {
 
 if(stateDiv == 1 && micros() - timeOld > rotTime / Div * (numDiv)){
 
   stateDiv = 0;
 
 }
 
 if(stateDiv == 0 && micros() - timeOld < rotTime / Div * (numDiv + 1)){
 
   stateDiv = 1;
 
   strip5.clear();
 
   strip4.clear();
 
   for(int i=0;i= Div) numDiv2 -= Div;
 
     strip5.setPixelColor(i, pic[numRot][numDiv2][i*2]);
 
     strip4.setPixelColor(i, pic[numRot][numDiv][i*2+1]);
 
   }
 
   strip5.show();
 
   strip4.show();
 
   numDiv++;
 
   if(numDiv >= Div ) numDiv = 0;
 
 }
 
}
 
void RotCount() {
 
 timeNow = micros();
 
 rotTime = timeNow - timeOld;
 
 timeOld = timeNow;
 
 numRot++;
 
 if(numRot >= Frame) numRot = 0;
 
}

显示图形数据创建方法(Python)

在Python代码中创建POV显示数据“graphics.h”。可以通过GIF或静止图像创建显示数据。

# -*- coding: utf-8 -*-
 
import cv2
 
import os
 
import math
 
from PIL import Image
 
#Array setting
 
NUMPIXELS = 57 #Number of LEDs
 
Div = 150 #Number of divisions per lap
 
Bright = 30 #LED Brightness
 
Led0Bright = 3 #Brightness of center LED [%]
 
#File creation
 
file = open('graphics.h', 'w')
 
file.write('#define NUMPIXELS ' + str(NUMPIXELS) + '\n')
 
file.write('#define Div ' + str(Div) + '\n' + '\n')
 
#file.write('#define Frame ' + str(Frame) + '\n' + '\n')
 
file.write('const uint32_t pic [Frame][Div][NUMPIXELS] = {' + '\n')
 
# Read GIF file
 
gif_file_name = "xxx.gif"
 
gif = cv2.VideoCapture(gif_file_name)
 
#Image conversion function
 
def polarConv(pic, i):
 
   imgOrgin = cv2.imread(pic) #Read image data
 
   h, w, _ = imgOrgin.shape #Get image size
 
   #Image reduction
 
   imgRedu = cv2.resize(imgOrgin,(math.floor((NUMPIXELS * 2 -1)/h *w), NUMPIXELS * 2 -1))
 
   #cv2.imwrite(str(i) + '-resize.jpg',imgRedu)
 
   #Reduced image center coordinates
 
   h2, w2, _ = imgRedu.shape
 
   wC = math.floor(w2 / 2)
 
   hC = math.floor(h2 / 2)
 
   #Polar coordinate conversion image preparation
 
   imgPolar = Image.new('RGB', (NUMPIXELS, Div))
 
   #Polar transformation
 
   file.write('\t{\n')
 
   for j in range(0, Div):
 
       file.write('\t\t{')
 
       for i in range(0, hC+1):
 
           #Get coordinate color
 
           rP = int(imgRedu[hC + math.ceil(i * math.cos(2*math.pi/Div*j)),
 
                        wC - math.ceil(i * math.sin(2*math.pi/Div*j)), 2]
 
                    * ((100 - Led0Bright) / NUMPIXELS * i + Led0Bright) / 100 * Bright /100)
 
           gP = int(imgRedu[hC + math.ceil(i * math.cos(2*math.pi/Div*j)),
 
                        wC - math.ceil(i * math.sin(2*math.pi/Div*j)), 1]
 
                    * ((100 - Led0Bright) / NUMPIXELS * i + Led0Bright) / 100 * Bright /100)
 
           bP = int(imgRedu[hC + math.ceil(i * math.cos(2*math.pi/Div*j)),
 
                        wC - math.ceil(i * math.sin(2*math.pi/Div*j)), 0]
 
                    * ((100 - Led0Bright) / NUMPIXELS * i + Led0Bright) / 100 * Bright /100)
 
           file.write('0x%02X%02X%02X' % (rP,gP,bP))
 
           if i == hC:
 
               file.write('},\n')
 
           else:
 
               file.write(', ')
 
           imgPolar.putpixel((i,j), (rP, gP, bP))
 
   file.write('\t},\n\n')
 
#Generate directory to save screen capture
 
dir_name = "screen_caps"
 
if not os.path.exists(dir_name):
 
   os.mkdir(dir_name)
 
i = 0
 
while True:
 
   is_success, frame = gif.read()
 
   # Exit when the file can not be read
 
   if not is_success:
 
       break
 
   # Write out to an image file
 
   img_name = str(i) + ".jpg"
 
   img_path = os.path.join(dir_name, img_name)
 
   cv2.imwrite(img_path, frame)
 
   #conversion
 
   polarConv(img_path, i)
 
   i += 1
 
file.write('};' + '\n' + '\n')
 
file.close()
 
#Inserting the number of frames at the beginning of the file
 
with open('graphics.h') as f:
 
   l = f.readlines()
 
l.insert(0, '#define Frame ' + str(i) + '\n')
 
with open('graphics.h', mode='w') as f:
 
   f.writelines(l)

测试GIF文件
我使用了以下GIF文件。帧数是16。

测试视频链接:http://v.qq.com/x/page/o08708on52f.html

推荐项目阅读:
使用SPRESENSE电路板的POV显示器
【ardunio项目】如何制作深受儿童喜爱的木制收音机
Arduino“反应计时器” - 我的孩子喜欢玩这个
ESP32项目:邮件警报
物联网植物监测仪,用 Particle Photon制作、IFTTT监测
开源NFC模块示例(一):arduino NFC近场通讯模块的简易教程和评测
开源NFC模块示例(二):与Arduino UNO开发板的配合
开源NFC模块示例(三):Arduino NFC模块使用方法分享,PN532模块,S50卡
开源NFC模块示例(四):如何制作Makerspace NFC组件管理系统
……
更多:创客项目

你可能感兴趣的:(Arduino项目制作)