by Andrea Stagi
/* ..... */
#define MSC_SUBCLASS_SCSI 0x06
#define MSC_PROTOCOL_BULK_ONLY 0x50
#ifndef USB_VERSION
#define USB_VERSION 0x210
#endif
/* ..... */
#include <WebUSB.h>
const WebUSBURL URLS[] = {
{ 1, "astagi.github.io/webusb/" },
{ 0, "localhost:8000" },
};
const uint8_t ALLOWED_ORIGINS[] = { 1, 2 };
WebUSB WebUSBSerial(URLS, 2, 2, ALLOWED_ORIGINS, 2);
#define Serial WebUSBSerial
sketch.ino
typedef struct {
uint8_t scheme;
const char* url;
} WebUSBURL;
WebUSBURL Structure
WebUSB(
const WebUSBURL* urls,
uint8_t numUrls,
uint8_t landingPage,
const uint8_t* allowedOrigins,
uint8_t numAllowedOrigins
);
WebUSB Constructor
#define Serial WebUSBSerial
void loop() {
if (Serial && Serial.available()) {
command = Serial.read();
/* ELABORATE!! */
Serial.flush();
}
}
WebUSB::WebUSB(
const WebUSBURL* urls, uint8_t numUrls,
uint8_t landingPage,
const uint8_t* allowedOrigins,
uint8_t numAllowedOrigins)
: PluggableUSBModule(2, 1, epType),
urls(urls), numUrls(numUrls),
landingPage(landingPage),
allowedOrigins(allowedOrigins),
numAllowedOrigins(numAllowedOrigins)
{
epType[0] = EP_TYPE_BULK_OUT;
epType[1] = EP_TYPE_BULK_IN;
PluggableUSB().plug(this);
}
int WebUSB::getDescriptor(USBSetup& setup) {
if (USB_BOS_DESCRIPTOR_TYPE == setup.wValueH) {
if (setup.wValueL == 0 && setup.wIndex == 0) {
int whole_size = 0;
// SEND BOS DESCRIPTOR PREFIX
// SEND LANDING PAGE VALUE
if (USB_SendControl(0, &landingPage, 1) < 0)
return -1;
whole_size += 1;
// SEND BOS DESCRIPTOR SUFFIX
return whole_size;
}
}
return 0;
}
const uint8_t BOS_DESCRIPTOR_PREFIX[] PROGMEM = {
0x05, // Length
0x0F, // Binary Object Store descriptor
0x39, 0x00, // Total length
0x02, // Number of device capabilities
// WebUSB Platform Capability descriptor
// (bVendorCode == 0x01).
0x18, // Length
0x10, // Device Capability descriptor
0x05, // Platform Capability descriptor
0x00, // Reserved
0x38, 0xB6, 0x08, 0x34, 0xA9, 0x09, 0xA0, 0x47,
0x8B, 0xFD, 0xA0, 0x76, 0x88, 0x15, 0xB6, 0x65,
0x00, 0x01, // Version 1.0
0x01, // Vendor request code
};
if (setup.bRequest == 0x01 && setup.wIndex == WEBUSB_REQUEST_GET_ALLOWED_ORIGINS)
{
uint8_t allowedOriginsPrefix[] = {
// Allowed Origins Header, bNumConfigurations = 1
0x05, 0x00, 0x0c + numAllowedOrigins, 0x00, 0x01,
// Configuration Subset Header, bNumFunctions = 1
0x04, 0x01, 0x01, 0x01,
// Function Subset Header, bFirstInterface = pluggedInterface
0x03 + numAllowedOrigins, 0x02, pluggedInterface
};
if (USB_SendControl(
0, &allowedOriginsPrefix,
sizeof(allowedOriginsPrefix)
) < 0)
return false;
return USB_SendControl(0, allowedOrigins, numAllowedOrigins) >= 0;
}
else if (setup.bRequest == 0x01 && setup.wIndex == WEBUSB_REQUEST_GET_URL)
{
if (setup.wValueL == 0 || setup.wValueL > numUrls)
return false;
const WebUSBURL& url = urls[setup.wValueL - 1];
uint8_t urlLength = strlen(url.url);
uint8_t descriptorLength = urlLength + 3;
if (USB_SendControl(0, &descriptorLength, 1) < 0)
return false;
uint8_t descriptorType = 3;
if (USB_SendControl(0, &descriptorType, 1) < 0)
return false;
if (USB_SendControl(0, &url.scheme, 1) < 0)
return false;
return USB_SendControl(0, url.url, urlLength) >= 0;
}
int WebUSB::getInterface(uint8_t* interfaceCount) {
*interfaceCount += 1; // uses 1 interface
WebUSBDescriptor webUSBInterface = {
D_INTERFACE(pluggedInterface, 2, 0xff, 0, 0),
D_ENDPOINT(
USB_ENDPOINT_OUT(pluggedEndpoint),
USB_ENDPOINT_TYPE_BULK, 0x40, 0
),
D_ENDPOINT(
USB_ENDPOINT_IN (pluggedEndpoint + 1),
USB_ENDPOINT_TYPE_BULK, 0x40, 0
)
};
return USB_SendControl(
0, &webUSBInterface,
sizeof(webUSBInterface)
);
}
const filters = [
{ 'vendorId': 0x2341, 'productId': 0x8036 },
{ 'vendorId': 0x2341, 'productId': 0x8037 },
];
return navigator.usb.requestDevice (
{ 'filters': filters }
).then(
device_ => device = device_;
);
return this.device.open()
.then(() => {
if (device.configuration === null) {
return device.selectConfiguration(1);
}
})
.then(() => device.claimInterface(2))
.then(() => device.controlTransferOut({
'requestType': 'class',
'recipient': 'interface',
'request': 0x22, // CDC_SET_CONTROL_LINE_STATE
'value': 0x01,
'index': 0x02}))
.then(() => {
readLoop();
});
let readLoop = () => {
device.transferIn(5, 64).then(result => {
console.log(result.data);
readLoop();
}, error => {
console.log(error);
});
};
device.transferOut(4, data);
from nanpy import ArduinoApi
a = ArduinoApi()
a.pinMode(13, a.OUTPUT)
a.digitalWrite(13, a.HIGH)
from nanpy import DallasTemperature
sensors = DallasTemperature(5)
n_sensors = sensors.getDeviceCount()
addresses = []
for i in range(n_sensors):
addresses.append(sensors.getAddress(i))
sensors.setResolution(12)
while True:
sensors.requestTemperatures()
for i in range(n_sensors):
temp = sensors.getTempC(i)