Zoom_H6: Library for controling Zoom H6 Recorder
This library enables sending control commands and receiving device status from the Zoom H6 audio recorder
This commit is contained in:
commit
9442036542
4 changed files with 198 additions and 0 deletions
19
library.json
Normal file
19
library.json
Normal file
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"name": "Zoom_H6_Remote",
|
||||
"version": "1.0.0-rc",
|
||||
"frameworks": "arduino",
|
||||
"platforms": "*",
|
||||
"keywords": "ZOOM,H6,Remote",
|
||||
"description": "Library for controling Zoom H6 audio recorder with Arduino framework",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/tomer99r/ZoomH6_Arduino.git"
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
"name": "Tomer Rubinstein",
|
||||
"email": "tomer99r@gmail.com",
|
||||
"maintainer": true
|
||||
}
|
||||
]
|
||||
}
|
10
library.properties
Normal file
10
library.properties
Normal file
|
@ -0,0 +1,10 @@
|
|||
name=Zoom_H6_Remote
|
||||
version=1.0.0-rc
|
||||
author=Tomer Rubinstein <tomer99r@gmail.com>
|
||||
maintainer=Tomer Rubinstein <tomer99r@gmail.com>
|
||||
sentence=Library for contorling Zoom H6 audio recorder with Arduino framework
|
||||
paragraph=This library enables sending commands and getting status from Zoom H6 audio recorder using Arduino framework.
|
||||
category=Device Control
|
||||
url=https://github.com/tomer99r/ZoomH6_Arduino.git
|
||||
includes=ZoomH6.h
|
||||
architectures=*
|
114
src/ZoomH6.cpp
Normal file
114
src/ZoomH6.cpp
Normal file
|
@ -0,0 +1,114 @@
|
|||
#include "ZoomH6.h"
|
||||
static const byte handshakeSeq[] = {0xC2, 0xE1, 0x31, 0x2E, 0x30, 0x30,0xA1,0x80,0x00 };
|
||||
static const byte handshakeReply[] = {0x82, 0x83, 0x80, 0x81};
|
||||
|
||||
ZoomH6Remote::ZoomH6Remote(HardwareSerial* serial, Stream* debug, uint32_t timeout) :
|
||||
_serial(serial), _debug(debug), _timeout(timeout) {}
|
||||
|
||||
/*This will write the data to the serial, and return the expected number of replys
|
||||
in case of failure the result is negative */
|
||||
int8_t ZoomH6Remote::writeWithReply(byte* data, size_t dataLength, byte* reply, size_t replyLength) {
|
||||
int8_t respCount = 0;
|
||||
|
||||
for (int i = 0; i < dataLength; ++i) {
|
||||
_serial->write(data[i]);
|
||||
}
|
||||
|
||||
uint32_t timeout = millis() + _timeout;
|
||||
do {
|
||||
if (_serial->available()) {
|
||||
byte resp = _serial->read();
|
||||
if (reply != nullptr) {
|
||||
reply[respCount % replyLength] = resp;
|
||||
}
|
||||
timeout = millis() + _timeout;
|
||||
respCount++;
|
||||
}
|
||||
|
||||
} while (millis() <= timeout);//respCount < replyLength);
|
||||
|
||||
return respCount;
|
||||
}
|
||||
|
||||
bool ZoomH6Remote::initialize() {
|
||||
byte reply[3] = {0};
|
||||
|
||||
if(*_serial) _serial->end();
|
||||
_serial->begin(2400, SERIAL_8N1); // connection to Zoom.
|
||||
|
||||
uint32_t timeout = millis() + 10000;
|
||||
while (!*_serial) {
|
||||
if(millis() > timeout) goto FAIL_TIME;
|
||||
}
|
||||
|
||||
timeout = millis() + 10000;
|
||||
do {
|
||||
if(_serial->available()) {
|
||||
reply[0] = _serial->read();
|
||||
} else {
|
||||
_serial->write(0x00);
|
||||
delay(200);
|
||||
}
|
||||
if(millis() > timeout) return false;
|
||||
} while(reply[0] != 0x82);
|
||||
|
||||
if (!writeWithReply(handshakeSeq, 1, reply, 1)) goto FAIL_TIME;
|
||||
if (reply[0] != handshakeReply[1]) goto FAIL_RES;
|
||||
|
||||
if (!writeWithReply(&handshakeSeq[1], 5, reply, 1)) goto FAIL_TIME;
|
||||
if (reply[0] != handshakeReply[2]) goto FAIL_RES;
|
||||
|
||||
if (!writeWithReply(&handshakeSeq[6], 1, reply, 1)) goto FAIL_TIME;
|
||||
if (reply[0] != handshakeReply[3]) goto FAIL_RES;
|
||||
|
||||
writeWithReply(&handshakeSeq[7], 2, reply, 3); //clear status
|
||||
printStatus(reply[1], reply[2]);
|
||||
|
||||
return true;
|
||||
FAIL_TIME:
|
||||
if (_debug) _debug->println("Failed handshake - timeout");
|
||||
return false;
|
||||
FAIL_RES:
|
||||
if (_debug) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
_debug->println(reply[i]);
|
||||
}
|
||||
_debug->println("Failed handshake - invalid return value");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ZoomH6Remote::printStatus(byte& high, byte& low) {
|
||||
if (_debug) {
|
||||
if (high == 0x00 && low == 0x00) _debug->println("No Channel Record Ready!");
|
||||
|
||||
if (high & StatusHigh::Record_on) _debug->println("Start Recording");
|
||||
if (high & StatusHigh::Channel_L_on) _debug->println("Left Channel Enabled");
|
||||
if (high & StatusHigh::Channel_R_on) _debug->println("Right Channel Enabled");
|
||||
if (high & StatusHigh::Channel_1_on) _debug->println("Channel 1 Enabled");
|
||||
|
||||
if (low & StatusLow::Channel_2_on) _debug->println("Channel 2 Enabled");
|
||||
if (low & StatusLow::Channel_3_on) _debug->println("Channel 3 Enabled");
|
||||
if (low & StatusLow::Channel_4_on) _debug->println("Channel 4 Enabled");
|
||||
}
|
||||
}
|
||||
|
||||
/* This method is used to transmit commands for the Zoom,
|
||||
* primary - the primary command
|
||||
* secondary - the sub command
|
||||
* gap - the time to set between sending a command to releasing it (getting the status) in millis
|
||||
* debug - verbose of result status to the debug serial
|
||||
*/
|
||||
bool ZoomH6Remote::sendCommand(byte primary, byte secondary, uint32_t gap, byte* reply) {
|
||||
byte command[2] = {primary, secondary};
|
||||
byte releaseCom[2] = {Commands::SecFunc, SubCommands::Release };
|
||||
|
||||
if (!writeWithReply(command, 2, reply, 3)) return false;
|
||||
if (reply != nullptr) printStatus(reply[1], reply[2]);
|
||||
|
||||
if (gap) delay(gap);
|
||||
|
||||
if (!writeWithReply(releaseCom, 2, nullptr, 3)) return false;
|
||||
|
||||
return true;
|
||||
}
|
55
src/ZoomH6.h
Normal file
55
src/ZoomH6.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
#ifndef ZOOM_H6_H
|
||||
#define ZOOM_H6_H
|
||||
#include "Arduino.h"
|
||||
|
||||
enum Commands {
|
||||
Record = 0x81,
|
||||
Play = 0x82,
|
||||
SkipBackward = 0x84,
|
||||
SkipForward = 0x88,
|
||||
Stop = 0x90,
|
||||
SecFunc = 0x80,
|
||||
};
|
||||
|
||||
enum SubCommands {
|
||||
Release = 0x00,
|
||||
Channel_L = 0x01,
|
||||
Channel_R = 0x02,
|
||||
Channel_1 = 0x04,
|
||||
Channel_2 = 0x08,
|
||||
Channel_3 = 0x10,
|
||||
Channel_4 = 0x20,
|
||||
VolumeDown = 0x40,
|
||||
VolumeUp = 0x80,
|
||||
};
|
||||
|
||||
enum StatusHigh {
|
||||
Record_on = 0x01,
|
||||
Channel_L_on = 0x20,
|
||||
Channel_R_on = 0x08,
|
||||
Channel_1_on = 0x02,
|
||||
};
|
||||
|
||||
enum StatusLow {
|
||||
Channel_2_on = 0x20,
|
||||
Channel_3_on = 0x08,
|
||||
Channel_4_on = 0x02,
|
||||
};
|
||||
class ZoomH6Remote {
|
||||
public:
|
||||
ZoomH6Remote(HardwareSerial* serial, Stream* debug = nullptr, uint32_t timeout = 40);
|
||||
~ZoomH6Remote() = default;
|
||||
|
||||
bool initialize();
|
||||
bool sendCommand(byte primary, byte secondary, uint32_t gap, byte* reply = nullptr);
|
||||
|
||||
private:
|
||||
int8_t writeWithReply(byte* data, size_t dataLength, byte* reply, size_t replyLength);
|
||||
void printStatus(byte& high, byte& low);
|
||||
|
||||
Stream* _debug;
|
||||
uint32_t _timeout;
|
||||
HardwareSerial* _serial;
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue