“刷卡音箱/zh”的版本间的差异

来自Microduino Wikipedia
跳转至: 导航搜索
(Created page with "{| style="width: 800px;" |- | ==概述== *项目名称:Microduino刷卡音箱 *目的:读取SD卡中的歌曲播放,通过刷卡改变曲目 *难度:中 *耗时:2小...")
 
组装
第105行: 第105行:
 
[[File:Musicstep6.jpg||600px|center]]
 
[[File:Musicstep6.jpg||600px|center]]
 
至此音乐盒拼装完成
 
至此音乐盒拼装完成
 +
==刷卡使用==
  
 
==注意事项==
 
==注意事项==

2015年11月30日 (一) 05:55的版本

概述

  • 项目名称:Microduino刷卡音箱
  • 目的:读取SD卡中的歌曲播放,通过刷卡改变曲目
  • 难度:中
  • 耗时:2小时
  • 制作者:
  • 简介:

刷卡音箱一般是指在市场上支持或者能够读取SD、TF等等这些内存处理器的音箱的基础上,增加了刷卡换曲目功能的音箱,与传统的电脑音箱,手机音箱相比,插卡音箱独有的解码功能,使得它更为消费者所青睐,正因如此,它才被成为音响帝国中的解码大王。插卡音箱以实用,方便,最大限度的满足音箱消费者的需求为设计理念,产品设计简洁,使用高品质喇叭,音质震撼,还原度高,即使在最大音量下破音依然不明显,是追求完美音质的明智选择,还原效果明显,失真度低,被誉为音响王国中的音乐天使。精简按键设计、屏幕显示,无须复杂操作,轻松使用。

材料清单

  • Microduino设备
模块 数量 功能
Microduino-Core+/zh 1 核心板
Microduino-USBTTL/zh 1 下载程序
Microduino-Audio/zh 1 解码,存储音乐文件
Microduino-Audio&shield/zh 1 拨轮,MicroSD卡
Microduino-Amplifier/zh 1 攻放
Microduino-OLED/zh 1 显示
Microduino-Cube-S1/zh 1 扩展板OLED接口
  • 其他设备
模块 数量 功能
OLED连接线 1 连接
Micro-USB线 1 下载程序、供电
喇叭 1 播放音频
MicroSD卡(可选) 1 存储音乐文件
尼龙螺丝&螺母 1 固定
木质外壳 1 外观,固定
音乐盒物料.jpg
音乐盒物料2.jpg

实验原理

Microduino-Audio板可解码并存储音乐文件,Microduino-Audio&shield 与喇叭连接实现音乐拨轮及大容量存储,Microduino-Cube-S1与Microduino-OLED连接可以直观的文字提示方式在OLED中显示音量及曲目。再将Microduino-USBTTL,Microduino-Core+与其他模块无序拼接即可实现插卡音箱功能。音箱外形采用木质外壳也可DIY自己的专属外壳。

外形.jpg
  • 主要传感器

Microduino-Audio

文档

调试过程

Microduino-Core+/zhMicroduino-USBTTL/zh堆叠在一起.用数据线将写好的程序通过Microduino-USBTTL/zh上传到Microduino-Core+/zh上。 注意:最好不要将所有模块堆叠在一起之后再上传程序

Download1.jpg

打开Arduino IDE编程软件,点击 【文件】->【打开】,打开插卡音箱文件夹后选择Microduino_Audio_ble\ Microduino_Audio_ble.ino 点击"√",编译程序。 点击【工具】,选择正确的板+处理器+端口。 点击"→",进行上传。

Downloadselectcore+.jpg
  • 使用Flash存储音乐(容量很小)

连接Audio模块到电脑。若成功识别,则“我的电脑”中会出现CD驱动,打开CD驱动。 注意:若未成功识别请检查数据线与模块之间是否插牢。如检查插牢还不能识别就换个电脑USB接口试试。

Dl4.jpg

连接成功能显示出一个名为Microduino-Audio的CD驱动器,然后执行以下步骤:

Dl5.jpg

打开驱动后选择MusicDownload.exe

Musicdl.jpg

打开后选择“音频加载”

Musicdl1.jpg

点击“浏览”后选择所有歌曲,点击“打开”(歌曲在Case1-4.mp3中)。 注意:Flash中音乐文件不能超过4M,因此显屏中只有Music Num:1-4号有歌曲,5-9号歌曲还是上一首歌。如果想要增加歌曲,则使用第一种方法即音乐存入MicroSD卡

Musicdl2.jpg

打开后点击返回“更新下载”,点击“更新”,点击更新,更新时间较长,请耐心等待

Musicdl3.jpg

当现显示“校验成功”后,拷贝音乐就成功了。 注意:校验成功后直接关闭窗口,不要再点击更新,否则又要重新更新

  • 使用TF卡存储音乐(容量随TF卡大小变化)

将Audio&Shield模块通过USB数据线连接到电脑,此时会识别出一个CD驱动一个可移动磁盘。双击可移动磁盘

TF步骤1.png

点击鼠标右键新建文件夹,命名为01(如需要多个可继续命名为02,03以此类推)

TF步骤2.jpg

之后将音乐存储进文件夹01中即可

TF步骤3.jpg

组装

如图,请点击查看大图并对应步骤进行拼装

  • Step1:首先将A1与OLED显示屏用螺丝钉和螺帽固定,再将传感器连接线接入OLED背面的接口
Musicstep1.jpg
  • Step2:将D1和C2分别插入B1接口
Musicstep2.jpg
  • Step3:将音响嵌入如图位置,再将A1和B1用D3拼装起来
Musicstep3.jpg
  • Step4:将音响嵌入如图位置,再将A1和B1用D3和D2拼装起来
Musicstep4.jpg
  • Step5:将C1与A1和B1进行合并,并将Core,USBTTL,Audio&Shield,Amplifier,Audio叠加在一起,插在底板上,并用D4固定
Musicstep5.jpg
  • Step6:将传感器线和音响线接入模块底板相应位置,再使用USB线接到USBTTL模块上
Musicstep6.jpg

至此音乐盒拼装完成

刷卡使用

注意事项

1. 如果发生:只能增加音量不能减少音量,只能增加歌曲号不能减少歌曲号,或反之。 原因:uiStep()中阈值设定不合理。

波轮动作 A6实测电压(V) 对应编码(电压/5*1023) 阈值设定
Default 3.3 675.18 >600
向下 0 0 0~50
向左 1.6 327.36 150~400
向右 2.6 531.96 450~600

在uiSetup中更改阈值设定

程序说明

CardPlayer.ino

#include "audio.h"
#include "JQ6500.h"
#include "JQ6500_def.h"
#include <SoftwareSerial.h>
#include <EEPROM.h>
//定义蓝牙通信串口
SoftwareSerial mySerial(2, 3); // RX, TX
#define VOICE mySerial  
JQ6500 AUDIO(&VOICE);         //声明audio类


#define PIN_key A0	//灰度传感器输入引脚

#include <Adafruit_NeoPixel.h>
#define PIN 6			//Lantern灯引脚
Adafruit_NeoPixel strip = Adafruit_NeoPixel(1, PIN, NEO_GRB + NEO_KHZ800);

#define music_num_MIN 1		//歌曲最小数,固定
#define music_num_MAX 10	//歌曲最大数,可改

int music_vol=26;  //初始音量0~30

//---------------------------------
boolean music_status = false;	//歌曲播放状态
int music_num = 1;				//歌曲序号

void setup() 
{
  Serial.begin(9600);

  strip.begin();	//初始化LED
  strip.show(); // Initialize all pixels to 'off'

  colorWipe(strip.Color(0, 255, 200), 10);	//初始化颜色 R,G,B

   AUDIO.init(DEVICE_TF,MODE_FOL,music_vol);		//初始化mp3模块
   AUDIO.pause();									//暂停播放
}

unsigned long time1,time2;

#define paper_val_MIN 100		//黑白传感器触发小值
#define paper_val_MAX 600		//黑白传感器触发大值
boolean paper_sta=false;
int paper_num=0;				//纸张格数

int LED_vol_sta=0;	//LED呼吸灯反转
int LED_vol=0;		//LED呼吸灯值


boolean key=HIGH;			//按键
boolean key_cache=LOW;		//检测按键松开缓存

boolean vokey(boolean _vokey)
{
  key=analogRead(PIN_key)<paper_val_MIN;	//触发时

  switch(_vokey)
  {
  case 0:
    if(!key && key_cache)		//按下松开后
    {
      key_cache=key;		//缓存作判断用
      return true;
    }
    else
    {
      key_cache=key;		//缓存作判断用
      return false;
    }
    break;
  case 1:
    if(key && !key_cache)		//按下松开后
    {
      key_cache=key;		//缓存作判断用
      return true;
    }
    else
    {
      key_cache=key;		//缓存作判断用
      return false;
    }
    break;
  }
}


void loop() 
{
  if(vokey(0))		//触发时
  {
    colorWipe(strip.Color(255, 255, 0), 10);
    paper_num++;	//计数
    // Serial.print("+");

    paper_sta=true;	//读取模式

    time1=millis();
  }

  if(millis()-time1>1000 && paper_num!=0)	//触发,并且闲置超过一秒,结束扫描
  {
     AUDIO.choose(paper_num);	//播放扫描歌曲
    Serial.println(paper_num);
    AUDIO.play();
    //Serial.println("");
    //Serial.print("num:");
    //Serial.print(paper_num);
    paper_num=0;		//归零 等待下次扫描

    paper_sta=false;	//读取模式结束
  }

  if(!paper_sta)		//非读取模式,LED呼吸
  {
    if(LED_vol>=255)
    {
      LED_vol_sta=1;
    }
    if(LED_vol<=0) 
    {
      LED_vol_sta=0;
    }

    if(!LED_vol_sta)
    {
      LED_vol+=4;
    }
    else
    {
      LED_vol-=4;
    }

    colorWipe(strip.Color(LED_vol, 0, 0), 10);		//呼吸灯显示亮度
  }

  delay(10);
}


// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
  for(uint16_t i=0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
    strip.show();
    delay(wait);
  }
}

Audio.h

#include "arduino.h"
#include <EEPROM.h>

#define EEPROM_write(address, p) {int i = 0; byte *pp = (byte*)&(p);for(; i < sizeof(p); i++) EEPROM.write(address+i, pp[i]);}
#define EEPROM_read(address, p)  {int i = 0; byte *pp = (byte*)&(p);for(; i < sizeof(p); i++) pp[i]=EEPROM.read(address+i);}

struct config_type
{
  int EEPROM_music_mode;
  int EEPROM_music_vol;
};

config_type config;      // 定义结构变量config,并定义config的内容

void eeprom_WRITE(int mode, int vol)
{
  config_type config;      // 定义结构变量config,并定义config的内容
  config.EEPROM_music_mode=mode;
  config.EEPROM_music_vol=vol;

  EEPROM_write(0, config);  // 变量config存储到EEPROM,地址0写入
}

config_type eeprom_READ()
{
  config_type config_readback;
  EEPROM_read(0, config_readback);
  return config_readback;
}

JQ6500.cpp

// 
// JQ6500 audio library for Arduino
//

#include "JQ6500.h"
#include "JQ6500_def.h"
#include <SoftwareSerial.h>

JQ6500::JQ6500(SoftwareSerial *ser) {
    common_init();
	audioSwSerial = ser;	
}

JQ6500::JQ6500(HardwareSerial *ser) {
    common_init();
	audioHwSerial = ser;
}

void JQ6500::common_init(void){
	audioSwSerial = NULL;
	audioHwSerial = NULL;
	
}

void JQ6500::begin(uint16_t baud){
	if(audioSwSerial) audioSwSerial->begin(baud);
	else			  audioHwSerial->begin(baud);
	delay(10);
}

void JQ6500::sendCommand(uint8_t cmd, uint8_t *buf, uint16_t len){
	sendBuffer[0] = STX;
	sendBuffer[1] = len+2;
	sendBuffer[2] = cmd;
	if(len > 0)
		memcpy(sendBuffer+3, buf, len);
	sendBuffer[len+3] = ETX;
	if(audioSwSerial)
		audioSwSerial->write(sendBuffer, 4+len);
	else
		audioHwSerial->write(sendBuffer, 4+len);
	delay(100);
}

void JQ6500::next(){
	
	sendCommand(CMD_NEXT, NULL, 0);
}

void JQ6500::prev(){
	
	sendCommand(CMD_PREV, NULL, 0);
}

void JQ6500::choose(uint16_t num){
	cmdBuffer[0] = num>>8;
	cmdBuffer[1] = num&0x00FF;
	sendCommand(CMD_CHOOSE, cmdBuffer, 2);
}

void JQ6500::volUp(){
	
	sendCommand(CMD_UP, NULL, 0);
}

void JQ6500::volDown(){
	
	sendCommand(CMD_DOWN, NULL, 0);
}

void JQ6500::volumn(uint8_t vol){
	cmdBuffer[0] = vol;
	sendCommand(CMD_VOL, cmdBuffer, 1);
}

void JQ6500::eq(uint8_t eq){
	cmdBuffer[0] = eq;
	sendCommand(CMD_EQ, cmdBuffer, 1);	
}

void JQ6500::setDevice(uint8_t device){
	cmdBuffer[0] = device;
	sendCommand(CMD_DEVICE, cmdBuffer, 1);
}

void JQ6500::sleep(){
	
	sendCommand(CMD_SLEEP, NULL, 0);
}

void JQ6500::reset(){
	
	sendCommand(CMD_RESET, NULL, 0);
}

void JQ6500::play(){
	
	sendCommand(CMD_PLAY, NULL, 0);
}

void JQ6500::pause(){
	
	sendCommand(CMD_PAUSE, NULL, 0);
}

void JQ6500::folder(uint8_t temp){
	cmdBuffer[0] = temp;
	sendCommand(CMD_FOLDER, cmdBuffer, 1);
}

void JQ6500::setMode(uint8_t temp){
	cmdBuffer[0] = temp;
	sendCommand(CMD_MODE, cmdBuffer, 1);
}

void JQ6500::chooseFile(uint8_t folder, uint8_t file){
	cmdBuffer[0] = folder;
	cmdBuffer[1] = file;
	sendCommand(CMD_FILE, cmdBuffer, 2);
}

void JQ6500::init(uint8_t device, uint8_t mode, uint8_t vol){
	begin(9600);
	delay(300);
	reset();
	setDevice(device);
	setMode(mode);
	volumn(vol);
}


uint16_t JQ6500::dataParse(){
	uint16_t sum = 0;
	uint8_t temp;
	if(audioSwSerial){
		while(audioSwSerial->available()){
			temp = char(audioSwSerial->read());
			if(temp>47&&temp<58){
				temp -=48;  
			}else if(temp>96&&temp<103){
				temp -=87;  
			}
			sum = sum*16+temp; 
		}
	}else{
		while(audioHwSerial->available()){
			temp = char(audioHwSerial->read());
			if(temp>47&&temp<58){
				temp -=48;  
			}else if(temp>96&&temp<103){
				temp -=87;  
			}
			sum = sum*16+temp; 
		}
	}
	return sum;	
}

uint16_t JQ6500::queryNum(uint8_t cmd){
	if(audioSwSerial)
		audioSwSerial->flush();
	else
		audioHwSerial->flush();
	sendCommand(cmd, NULL, 0);	
    delay(100);	
	return dataParse();	
}

uint16_t JQ6500::queryTF(){
	return queryNum(QUERY_TF);	
}

uint16_t JQ6500::queryTFFile(){
    return queryNum(QUERY_TF_FILE);	
}

uint16_t JQ6500::queryFlash(){
    return queryNum(QUERY_FLASH);	
}

uint16_t JQ6500::queryFlashFile(){
    return queryNum(QUERY_FLASH_FILE);	
}

uint16_t JQ6500::queryTotalTime(){	
    return queryNum(QUERY_TTIME);	
}

uint16_t JQ6500::queryPlayTime(){
    return queryNum(QUERY_PTIME);	
}

String JQ6500::queryName(){
	String nameCache = "";
	char temp;
	uint16_t i = 0;
	if(audioSwSerial)
		audioSwSerial->flush();
	else
		audioHwSerial->flush();
	sendCommand(QUERY_NAME, NULL, 0);	
    delay(100);
	if(audioSwSerial){
		while(audioSwSerial->available()){
			temp = audioSwSerial->read();
			nameCache += temp;
			if(temp == 32){
				i++;	
			}else{
				i = 0;
			}
			if(i >= 3){
				i = 0;
				nameCache.replace("   ", ".");
			}
		}
	}else{
		while(audioHwSerial->available()){
			temp = audioHwSerial->read();
			nameCache += temp;
			if(temp == 32){
				i++;	
			}else{
				i = 0;
			}
			if(i >= 3){
				i = 0;
				nameCache.replace("   ", ".");
			}
		}
	}
	return nameCache;	
}

//
// END OF FILE
//

JQ6500.h

// 
// JQ6500 audio library for Arduino
// VERSION: 0.1.0
//

#ifndef __JQ6500_H__
#define __JQ6500_H__

#include <Arduino.h>
#include <SoftwareSerial.h>
 
#define AUDIO_VERSION "0.1.0"

#define STX 0x7E
#define ETX 0xEF

#define CMD_NEXT    0x01
#define CMD_PREV    0x02
#define CMD_CHOOSE  0x03
#define CMD_UP      0x04
#define CMD_DOWN    0x05
#define CMD_VOL     0x06
#define CMD_EQ      0x07
#define CMD_DEVICE  0x09
#define CMD_SLEEP   0x0A
#define CMD_RESET   0x0C
#define CMD_PLAY    0x0D
#define CMD_PAUSE   0x0E
#define CMD_FOLDER  0x0F
#define CMD_MODE    0x11
#define CMD_FILE    0x12

#define QUERY_STA   	0x42
#define QUERY_VOL   	0x43
#define QUERY_EQ    	0x44
#define QUERY_MODE  	0x45
#define QUERY_VERSION 	0x46
#define QUERY_TF    	0x47
#define QUERY_DISK  	0x48
#define QUERY_FLASH 	0x49
#define QUERY_TF_FILE 	0x4B
#define QUERY_DISK_FILE 0x4C
#define QUERY_FLASH_FILE	0x4D
#define QUERY_PTIME 	0x50
#define QUERY_TTIME 	0x51
#define QUERY_NAME  	0x52
#define QUERY_FILES 	0x53


class JQ6500{
public:
	JQ6500(SoftwareSerial *ser);
	JQ6500(HardwareSerial *ser);
	
	void begin(uint16_t baud);
	void next();
	void prev();
	void choose(uint16_t num);
	void volUp();
	void volDown();
	void volumn(uint8_t vol);
	void eq(uint8_t eq);
	void setDevice(uint8_t device);
	void sleep();
	void reset();
	void play();
	void pause();
	void folder(uint8_t temp);
	void setMode(uint8_t temp);
	void chooseFile(uint8_t folder, uint8_t file);
	void init(uint8_t device, uint8_t mode, uint8_t vol);
	
	uint16_t queryTF();
	uint16_t queryTFFile();
	uint16_t queryFlash();
	uint16_t queryFlashFile();
	uint16_t queryTotalTime();
	uint16_t queryPlayTime();
	String queryName();
	
private:
	uint8_t sendBuffer[8];
	uint8_t cmdBuffer[8];

	SoftwareSerial *audioSwSerial;
	HardwareSerial *audioHwSerial;
  
	void common_init(void);
	void sendCommand(uint8_t cmd, uint8_t *buf, uint16_t len);
	uint16_t dataParse();
	uint16_t queryNum(uint8_t cmd);
};

#endif
//
// END OF FILE
//

JQ6500_def

// 
// AM2321 Temperature & Humidity Sensor library for Arduino
// VERSION: 0.1.0
//
// The MIT License (MIT)
//
// Copyright (c) 2013 Wang Dong
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

#ifndef __JQ6500_DEF_H__
#define __JQ6500_DEF_H__

#define EQ_NORMAL    	0x00
#define EQ_POP    		0x01
#define EQ_ROCK  		0x02
#define EQ_JAZZ      	0x03
#define EQ_CLASSIC    	0x04
#define EQ_BASE			0x05

#define DEVICE_U    	0x00
#define DEVICE_TF    	0x01
#define DEVICE_AUX  	0x02
#define DEVICE_SLEEP    0x03
#define DEVICE_FLASH    0x04

#define MODE_ALL		0x00
#define MODE_FOL		0x01
#define MODE_ONE		0x02
#define MODE_RAM		0x03
#define	MODE_ONE_STOP	0x04


#endif
//
// END OF FILE
//

视频