Skip to content

Commit

Permalink
added: support for ambioder http://gabriel-lg.github.io/Ambioder/ (th…
Browse files Browse the repository at this point in the history
…anks Lambertus)
  • Loading branch information
bob.loosen committed Dec 3, 2013
1 parent 626d934 commit fe489f2
Show file tree
Hide file tree
Showing 7 changed files with 296 additions and 1 deletion.
37 changes: 37 additions & 0 deletions conf/ambioder.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#config file for ambioder

[global]
interface 127.0.0.1
port 19333

[device]
name device1
type ambioder
output /dev/ttyUSB0
channels 3
precision 255
interval 20000
rate 19200
debug off #turn this on to see what is sent over the serial port
delayafteropen 100000


[color]
name red
rgb FF0000

[color]
name green
rgb 00FF00

[color]
name blue
rgb 0000FF

[light]
name light1
color red device1 1
color green device1 2
color blue device1 3
hscan 0 100
vscan 0 100
1 change: 1 addition & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ boblightd_SOURCES = \
device/devicers232.cpp \
device/deviceltbl.cpp \
device/devicedioder.cpp \
device/deviceambioder.cpp \
util/signaltimer.cpp \
util/daemonize.cpp

Expand Down
66 changes: 65 additions & 1 deletion src/configuration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ bool CConfig::CheckDeviceConfig()
continue; //can't check these here
}
else if (key == "rate" || key == "channels" || key == "interval" || key == "period" ||
key == "bits" || key == "delayafteropen" || key == "max")
key == "bits" || key == "delayafteropen" || key == "max" || key == "precision")
{ //these are of type integer not lower than 1
int64_t ivalue;
if (!StrToInt(value, ivalue) || ivalue < 1 || (key == "bits" && ivalue > 32) || (key == "max" && ivalue > 0xFFFFFFFF))
Expand Down Expand Up @@ -750,6 +750,17 @@ bool CConfig::BuildDeviceConfig(std::vector<CDevice*>& devices, CClientsHandler&
}
devices.push_back(device);
}
else if (type == "ambioder")
{
CDevice* device = NULL;
if (!BuildAmbioder(device, i, clients))
{
if (device)
delete device;
return false;
}
devices.push_back(device);
}
else if (type == "ibelight")
{
#ifdef HAVE_LIBUSB
Expand Down Expand Up @@ -1154,6 +1165,59 @@ bool CConfig::BuildDioder(CDevice*& device, int devicenr, CClientsHandler& clien

}

bool CConfig::BuildAmbioder(CDevice*& device, int devicenr, CClientsHandler& clients)
{
CDeviceAmbioder* ambioderdevice = new CDeviceAmbioder(clients);

device = ambioderdevice;

if (!SetDeviceName(ambioderdevice, devicenr))
return false;

if (!SetDeviceOutput(ambioderdevice, devicenr))
return false;

if (!SetDeviceChannels(ambioderdevice, devicenr))
return false;

if (!SetDeviceRate(ambioderdevice, devicenr))
return false;

if (!SetDeviceInterval(ambioderdevice, devicenr))
return false;

if (!SetDevicePrecision(ambioderdevice, devicenr))
return false;

SetDeviceAllowSync(device, devicenr);
SetDeviceDebug(device, devicenr);
SetDeviceDelayAfterOpen(device, devicenr);
SetDeviceThreadPriority(device, devicenr);

device->SetType(AMBIODER);

return true;

}

bool CConfig::SetDevicePrecision(CDeviceAmbioder*& device, int devicenr)
{
string line, strvalue;
int linenr = GetLineWithKey("precision", m_devicelines[devicenr].lines, line);
if (linenr == -1)
return false;

GetWord(line, strvalue);

int precision;
StrToInt(strvalue, precision);

if(!device->SetPrecision(precision))
return false;

return true;
}

#ifdef HAVE_LINUX_SPI_SPIDEV_H
bool CConfig::BuildSPI(CDevice*& device, int devicenr, CClientsHandler& clients, const std::string& type)
{
Expand Down
4 changes: 4 additions & 0 deletions src/configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "device/device.h"
#include "device/devicers232.h"
#include "device/devicedioder.h"
#include "device/deviceambioder.h"

#ifdef HAVE_LIBPORTAUDIO
#include "device/devicesound.h"
Expand Down Expand Up @@ -103,6 +104,9 @@ class CConfig
bool BuildRS232(CDevice*& device, int devicenr, CClientsHandler& clients, const std::string& type);
bool BuildLtbl(CDevice*& device, int devicenr, CClientsHandler& clients);
bool BuildDioder(CDevice*& device, int devicenr, CClientsHandler& clients);
bool BuildAmbioder(CDevice*& device, int devicenr, CClientsHandler& clients);
bool SetDevicePrecision(CDeviceAmbioder*& device, int devicenr);

#ifdef HAVE_LIBPORTAUDIO
bool BuildSound(CDevice*& device, int devicenr, CClientsHandler& clients);
#endif
Expand Down
2 changes: 2 additions & 0 deletions src/device/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
#define LPD8806 11
#define WS2801 12
#define LIGHTPACK 13
#define AMBIODER 14


#include <string>
#include <vector>
Expand Down
149 changes: 149 additions & 0 deletions src/device/deviceambioder.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
/*
* boblight
* Copyright (C) Bob 2009
*
* boblight is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* boblight is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "deviceambioder.h"
#include "util/log.h"
#include "util/misc.h"
#include "util/timeutils.h"

#define AMBIODER_PWM_PERIOD 255
/*
support for Ambioder device: http://gabriel-lg.github.com/Ambioder/
protocol:
commands are sent as 6/8-byte sequences:
hex: [0x0X 0x1X] 0x2X 0x3X 0x4X 0x5X 0x6X 0x7X
the least significant nibbles are combined to form (in order):
pwm period, red, green blue.
*/

static const uint8_t ambioder_off[] = {0x0F, 0x1F, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70};

CDeviceAmbioder::CDeviceAmbioder(CClientsHandler& clients) : CDeviceRS232(clients)
{
m_buff = new uint8_t[8];
}


bool CDeviceAmbioder::SetupDevice()
{
m_timer.SetInterval(m_interval);

if (!OpenSerialPort())
return false;

m_serialport.PrintToStdOut(m_debug); //print serial data to stdout when debug mode is on

if (m_delayafteropen > 0)
USleep(m_delayafteropen, &m_stop);

//turn off the lights
memcpy(m_buff, ambioder_off, 8);
if (m_serialport.Write(m_buff, 8) == -1)
{
LogError("%s: %s", m_name.c_str(), m_serialport.GetError().c_str());
return false;
}

Log("%s: %d colors @ %.1fHz", m_name.c_str(), (int)pow(m_precision+1, 3), (float)2000000/(35*m_precision) );

return true;

}

/**
* Set the precision for ambioder. Valid range is 15 to 255.
* Higher precision means more colors can be generated.
* Higher precision will result in a lower PWM frequency.
*r
* The number of colors/pwm frequency are calculated as follows:
* colors = (precision + 1)^3
* frequency = 2000000 / (35 * precision)
*
* e.g. precision = 127 gives:
* colors = (127 + 1)^3 = 2,097,152 colors
* frequency = 2000000 / (25 * 127) = 449.94Hz
*/
bool CDeviceAmbioder::SetPrecision(int precision)
{
if(precision < 15 || precision > 255)
{
LogError("%s: invalid precision value: %d (valid range: 15~255)", m_name.c_str(), precision);
return false;
}

m_precision = precision;

return true;
}


bool CDeviceAmbioder::WriteOutput()
{
//get the channel values from the clienshandler
int64_t now = GetTimeUs();
m_clients.FillChannels(m_channels, now, this);

//create the command sequence
if(m_channels.size() >= 3)
{
uint8_t period = m_precision;
uint8_t red = Clamp(Round32(m_channels[0].GetValue(now) * m_precision), 0, m_precision);
uint8_t green = Clamp(Round32(m_channels[1].GetValue(now) * m_precision), 0, m_precision);
uint8_t blue = Clamp(Round32(m_channels[2].GetValue(now) * m_precision), 0, m_precision);
m_buff[0] = 0x00 | ((period >> 4) & 0x0F);
m_buff[1] = 0x10 | (period & 0x0F);
m_buff[2] = 0x20 | ((red >> 4) & 0x0F);
m_buff[3] = 0x30 | (red & 0x0F);
m_buff[4] = 0x40 | ((green >> 4) & 0x0F);
m_buff[5] = 0x50 | (green & 0x0F);
m_buff[6] = 0x60 | ((blue >> 4) &0x0F);
m_buff[7] = 0x70 | (blue & 0x0F);
}
else
{
memcpy(m_buff, ambioder_off, 8);
}
//write output to the serial port
if (m_serialport.Write(m_buff, 8) == -1)
{
LogError("%s: %s", m_name.c_str(), m_serialport.GetError().c_str());
return false;
}

m_timer.Wait(); //wait for the timer to signal us

return true;
}

void CDeviceAmbioder::CloseDevice()
{
//turn off the lights
memcpy(m_buff, ambioder_off, 8);
if (m_serialport.Write(m_buff, 8) == -1)
{
LogError("%s: %s", m_name.c_str(), m_serialport.GetError().c_str());
}
m_serialport.Write(m_buff, 4);

m_serialport.Close();
}

CDeviceAmbioder::~CDeviceAmbioder()
{
delete m_buff;
}
38 changes: 38 additions & 0 deletions src/device/deviceambioder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* boblight
* Copyright (C) Bob 2009
*
* boblight is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* boblight is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "devicers232.h"

#ifndef DEVICEAMBIODER
#define DEVICEAMBIODER

class CDeviceAmbioder : public CDeviceRS232
{
public:
CDeviceAmbioder(CClientsHandler& clients);
bool SetPrecision(int max);

private:
int m_precision;
bool SetupDevice();
bool WriteOutput();
void CloseDevice();
~CDeviceAmbioder();
};

#endif //DEVICEAMBIODER

0 comments on commit fe489f2

Please sign in to comment.