BlinkM_funcs.h
Go to the documentation of this file.
1 /*
2  * BlinkM_funcs.h -- Arduino 'library' to control BlinkM
3  * --------------
4  *
5  *
6  * Note: original version of this file lives with the BlinkMTester sketch
7  *
8  * Note: all the functions are declared 'static' because
9  * it saves about 1.5 kbyte in code space in final compiled sketch.
10  * A C++ library of this costs a 1kB more.
11  *
12  * 2007-8, Tod E. Kurt, ThingM, http://thingm.com/
13  *
14  * version: 20081101
15  *
16  * history:
17  * 20080101 - initial release
18  * 20080203 - added setStartupParam(), bugfix receiveBytes() from Dan Julio
19  * 20081101 - fixed to work with Arduino-0012, added MaxM commands,
20  * added test script read/write functions, cleaned up some functions
21  * 20090121 - added I2C bus scan functions, has dependencies on private
22  * functions inside Wire library, so might break in the future
23  * 20100420 - added BlinkM_startPower and _stopPower
24  *
25  */
26 
27 #include <Wire.h>
28 
29 extern "C" {
30 #include "utility/twi.h" // from Wire library, so we can do bus scanning
31 }
32 
33 
34 // format of light script lines: duration, command, arg1,arg2,arg3
35 typedef struct _blinkm_script_line {
36  uint8_t dur;
37  uint8_t cmd[4]; // cmd,arg1,arg2,arg3
39 
40 
41 // Call this first (when powering BlinkM from a power supply)
42 static void BlinkM_begin()
43 {
44  Wire.begin(); // join i2c bus (address optional for master)
45 }
46 
47 /*
48  * actually can't do this either, because twi_init() has THREE callocs in it too
49  *
50 static void BlinkM_reset()
51 {
52  twi_init(); // can't just call Wire.begin() again because of calloc()s there
53 }
54 */
55 
56 //
57 // each call to twi_writeTo() should return 0 if device is there
58 // or other value (usually 2) if nothing is at that address
59 //
60 static void BlinkM_scanI2CBus(byte from, byte to,
61  void(*callback)(byte add, byte result) )
62 {
63  byte rc;
64  byte data = 0; // not used, just an address to feed to twi_writeTo()
65  for( byte addr = from; addr <= to; addr++ ) {
66  rc = twi_writeTo(addr, &data, 0, 1, 1);
67  callback( addr, rc );
68  }
69 }
70 
71 //
72 //
73 static int8_t BlinkM_findFirstI2CDevice()
74 {
75  byte rc;
76  byte data = 0; // not used, just an address to feed to twi_writeTo()
77  for( byte addr=1; addr < 120; addr++ ) { // only scan addrs 1-120
78  rc = twi_writeTo(addr, &data, 0, 1, 1);
79  if( rc == 0 ) return addr; // found an address
80  }
81  return -1; // no device found in range given
82 }
83 
84 // FIXME: make this more Arduino-like
85 static void BlinkM_startPowerWithPins(byte pwrpin, byte gndpin)
86 {
87  DDRC |= _BV(pwrpin) | _BV(gndpin); // make outputs
88  PORTC &=~ _BV(gndpin);
89  PORTC |= _BV(pwrpin);
90 }
91 
92 // FIXME: make this more Arduino-like
93 static void BlinkM_stopPowerWithPins(byte pwrpin, byte gndpin)
94 {
95  DDRC &=~ (_BV(pwrpin) | _BV(gndpin));
96 }
97 
98 //
99 static void BlinkM_startPower()
100 {
101  BlinkM_startPowerWithPins( PORTC3, PORTC2 );
102 }
103 
104 //
105 static void BlinkM_stopPower()
106 {
107  BlinkM_stopPowerWithPins( PORTC3, PORTC2 );
108 }
109 
110 // General version of BlinkM_beginWithPower().
111 // Call this first when BlinkM is plugged directly into Arduino
112 static void BlinkM_beginWithPowerPins(byte pwrpin, byte gndpin)
113 {
114  BlinkM_startPowerWithPins(pwrpin,gndpin);
115  delay(100); // wait for things to stabilize
116  Wire.begin();
117 }
118 
119 // Call this first when BlinkM is plugged directly into Arduino
120 // FIXME: make this more Arduino-like
122 {
123  BlinkM_beginWithPowerPins( PORTC3, PORTC2 );
124 }
125 
126 // sends a generic command
127 static void BlinkM_sendCmd(byte addr, byte* cmd, int cmdlen)
128 {
129  Wire.beginTransmission(addr);
130  for( byte i=0; i<cmdlen; i++)
131  Wire.write(cmd[i]);
132  Wire.endTransmission();
133 }
134 
135 // receives generic data
136 // returns 0 on success, and -1 if no data available
137 // note: responsiblity of caller to know how many bytes to expect
138 static int BlinkM_receiveBytes(byte addr, byte* resp, byte len)
139 {
140  Wire.requestFrom(addr, len);
141  if( Wire.available() ) {
142  for( int i=0; i<len; i++)
143  resp[i] = Wire.read();
144  return 0;
145  }
146  return -1;
147 }
148 
149 // Sets the I2C address of the BlinkM.
150 // Uses "general call" broadcast address
151 static void BlinkM_setAddress(byte newaddress)
152 {
153  Wire.beginTransmission(0x00); // general call (broadcast address)
154  Wire.write('A');
155  Wire.write(newaddress);
156  Wire.write(0xD0);
157  Wire.write(0x0D); // dood!
158  Wire.write(newaddress);
159  Wire.endTransmission();
160  delay(50); // just in case
161 }
162 
163 
164 // Gets the I2C address of the BlinKM
165 // Kind of redundant when sent to a specific address
166 // but uses to verify BlinkM communication
167 static int BlinkM_getAddress(byte addr)
168 {
169  Wire.beginTransmission(addr);
170  Wire.write('a');
171  Wire.endTransmission();
172  Wire.requestFrom(addr, (byte)1); // general call
173  if( Wire.available() ) {
174  byte b = Wire.read();
175  return b;
176  }
177  return -1;
178 }
179 
180 // Gets the BlinkM firmware version
181 static int BlinkM_getVersion(byte addr)
182 {
183  Wire.beginTransmission(addr);
184  Wire.write('Z');
185  Wire.endTransmission();
186  Wire.requestFrom(addr, (byte)2);
187  if( Wire.available() ) {
188  byte major_ver = Wire.read();
189  byte minor_ver = Wire.read();
190  return (major_ver<<8) + minor_ver;
191  }
192  return -1;
193 }
194 
195 // Demonstrates how to verify you're talking to a BlinkM
196 // and that you know its address
197 static int BlinkM_checkAddress(byte addr)
198 {
199  //Serial.print("Checking BlinkM address...");
200  int b = BlinkM_getAddress(addr);
201  if( b==-1 ) {
202  //Serial.println("No response, that's not good");
203  return -1; // no response
204  }
205  //Serial.print("received addr: 0x");
206  //Serial.print(b,HEX);
207  if( b != addr )
208  return 1; // error, addr mismatch
209  else
210  return 0; // match, everything okay
211 }
212 
213 // Sets the speed of fading between colors.
214 // Higher numbers means faster fading, 255 == instantaneous fading
215 static void BlinkM_setFadeSpeed(byte addr, byte fadespeed)
216 {
217  Wire.beginTransmission(addr);
218  Wire.write('f');
219  Wire.write(fadespeed);
220  Wire.endTransmission();
221 }
222 
223 // Sets the light script playback time adjust
224 // The timeadj argument is signed, and is an additive value to all
225 // durations in a light script. Set to zero to turn off time adjust.
226 static void BlinkM_setTimeAdj(byte addr, byte timeadj)
227 {
228  Wire.beginTransmission(addr);
229  Wire.write('t');
230  Wire.write(timeadj);
231  Wire.endTransmission();
232 }
233 
234 // Fades to an RGB color
235 static void BlinkM_fadeToRGB(byte addr, byte red, byte grn, byte blu)
236 {
237  Wire.beginTransmission(addr);
238  Wire.write('c');
239  Wire.write(red);
240  Wire.write(grn);
241  Wire.write(blu);
242  Wire.endTransmission();
243 }
244 
245 // Fades to an HSB color
246 static void BlinkM_fadeToHSB(byte addr, byte hue, byte saturation, byte brightness)
247 {
248  Wire.beginTransmission(addr);
249  Wire.write('h');
250  Wire.write(hue);
251  Wire.write(saturation);
252  Wire.write(brightness);
253  Wire.endTransmission();
254 }
255 
256 // Sets an RGB color immediately
257 static void BlinkM_setRGB(byte addr, byte red, byte grn, byte blu)
258 {
259  Wire.beginTransmission(addr);
260  Wire.write('n');
261  Wire.write(red);
262  Wire.write(grn);
263  Wire.write(blu);
264  Wire.endTransmission();
265 }
266 
267 // Fades to a random RGB color
268 static void BlinkM_fadeToRandomRGB(byte addr, byte rrnd, byte grnd, byte brnd)
269 {
270  Wire.beginTransmission(addr);
271  Wire.write('C');
272  Wire.write(rrnd);
273  Wire.write(grnd);
274  Wire.write(brnd);
275  Wire.endTransmission();
276 }
277 // Fades to a random HSB color
278 static void BlinkM_fadeToRandomHSB(byte addr, byte hrnd, byte srnd, byte brnd)
279 {
280  Wire.beginTransmission(addr);
281  Wire.write('H');
282  Wire.write(hrnd);
283  Wire.write(srnd);
284  Wire.write(brnd);
285  Wire.endTransmission();
286 }
287 
288 //
289 static void BlinkM_getRGBColor(byte addr, byte* r, byte* g, byte* b)
290 {
291  Wire.beginTransmission(addr);
292  Wire.write('g');
293  Wire.endTransmission();
294  Wire.requestFrom(addr, (byte)3);
295  if( Wire.available() ) {
296  *r = Wire.read();
297  *g = Wire.read();
298  *b = Wire.read();
299  }
300 }
301 
302 //
303 static void BlinkM_playScript(byte addr, byte script_id, byte reps, byte pos)
304 {
305  Wire.beginTransmission(addr);
306  Wire.write('p');
307  Wire.write(script_id);
308  Wire.write(reps);
309  Wire.write(pos);
310  Wire.endTransmission();
311 }
312 
313 //
314 static void BlinkM_stopScript(byte addr)
315 {
316  Wire.beginTransmission(addr);
317  Wire.write('o');
318  Wire.endTransmission();
319 }
320 
321 //
322 static void BlinkM_setScriptLengthReps(byte addr, byte script_id,
323  byte len, byte reps)
324 {
325  Wire.beginTransmission(addr);
326  Wire.write('L');
327  Wire.write(script_id);
328  Wire.write(len);
329  Wire.write(reps);
330  Wire.endTransmission();
331 }
332 
333 // Fill up script_line with data from a script line
334 // currently only script_id = 0 works (eeprom script)
335 static void BlinkM_readScriptLine(byte addr, byte script_id,
336  byte pos, blinkm_script_line* script_line)
337 {
338  Wire.beginTransmission(addr);
339  Wire.write('R');
340  Wire.write(script_id);
341  Wire.write(pos);
342  Wire.endTransmission();
343  Wire.requestFrom(addr, (byte)5);
344  while( Wire.available() < 5 ) ; // FIXME: wait until we get 7 bytes
345  script_line->dur = Wire.read();
346  script_line->cmd[0] = Wire.read();
347  script_line->cmd[1] = Wire.read();
348  script_line->cmd[2] = Wire.read();
349  script_line->cmd[3] = Wire.read();
350 }
351 
352 //
353 static void BlinkM_writeScriptLine(byte addr, byte script_id,
354  byte pos, byte dur,
355  byte cmd, byte arg1, byte arg2, byte arg3)
356 {
357 #ifdef BLINKM_FUNCS_DEBUG
358  Serial.print("writing line:"); Serial.print(pos,DEC);
359  Serial.print(" with cmd:"); Serial.print(cmd);
360  Serial.print(" arg1:"); Serial.println(arg1,HEX);
361 #endif
362  Wire.beginTransmission(addr);
363  Wire.write('W');
364  Wire.write(script_id);
365  Wire.write(pos);
366  Wire.write(dur);
367  Wire.write(cmd);
368  Wire.write(arg1);
369  Wire.write(arg2);
370  Wire.write(arg3);
371  Wire.endTransmission();
372 
373 }
374 
375 //
376 static void BlinkM_writeScript(byte addr, byte script_id,
377  byte len, byte reps,
378  blinkm_script_line* lines)
379 {
380 #ifdef BLINKM_FUNCS_DEBUG
381  Serial.print("writing script to addr:"); Serial.print(addr,DEC);
382  Serial.print(", script_id:"); Serial.println(script_id,DEC);
383 #endif
384  for(byte i=0; i < len; i++) {
385  blinkm_script_line l = lines[i];
386  BlinkM_writeScriptLine( addr, script_id, i, l.dur,
387  l.cmd[0], l.cmd[1], l.cmd[2], l.cmd[3]);
388  delay(20); // must wait for EEPROM to be programmed
389  }
390  BlinkM_setScriptLengthReps(addr, script_id, len, reps);
391 }
392 
393 //
394 static void BlinkM_setStartupParams(byte addr, byte mode, byte script_id,
395  byte reps, byte fadespeed, byte timeadj)
396 {
397  Wire.beginTransmission(addr);
398  Wire.write('B');
399  Wire.write(mode); // default 0x01 == Play script
400  Wire.write(script_id); // default 0x00 == script #0
401  Wire.write(reps); // default 0x00 == repeat infinitely
402  Wire.write(fadespeed); // default 0x08 == usually overridden by sketch
403  Wire.write(timeadj); // default 0x00 == sometimes overridden by sketch
404  Wire.endTransmission();
405 }
406 
407 
408 // Gets digital inputs of the BlinkM
409 // returns -1 on failure
410 static int BlinkM_getInputsO(byte addr)
411 {
412  Wire.beginTransmission(addr);
413  Wire.write('i');
414  Wire.endTransmission();
415  Wire.requestFrom(addr, (byte)1);
416  if( Wire.available() ) {
417  byte b = Wire.read();
418  return b;
419  }
420  return -1;
421 }
422 
423 // Gets digital inputs of the BlinkM
424 // stores them in passed in array
425 // returns -1 on failure
426 static int BlinkM_getInputs(byte addr, byte inputs[])
427 {
428  Wire.beginTransmission(addr);
429  Wire.write('i');
430  Wire.endTransmission();
431  Wire.requestFrom(addr, (byte)4);
432  while( Wire.available() < 4 ) ; // FIXME: wait until we get 4 bytes
433 
434  inputs[0] = Wire.read();
435  inputs[1] = Wire.read();
436  inputs[2] = Wire.read();
437  inputs[3] = Wire.read();
438 
439  return 0;
440 }
static int BlinkM_receiveBytes(byte addr, byte *resp, byte len)
Definition: BlinkM_funcs.h:138
static void BlinkM_setTimeAdj(byte addr, byte timeadj)
Definition: BlinkM_funcs.h:226
static void BlinkM_getRGBColor(byte addr, byte *r, byte *g, byte *b)
Definition: BlinkM_funcs.h:289
static void BlinkM_setAddress(byte newaddress)
Definition: BlinkM_funcs.h:151
static void BlinkM_stopScript(byte addr)
Definition: BlinkM_funcs.h:314
static void BlinkM_stopPowerWithPins(byte pwrpin, byte gndpin)
Definition: BlinkM_funcs.h:93
static void BlinkM_writeScript(byte addr, byte script_id, byte len, byte reps, blinkm_script_line *lines)
Definition: BlinkM_funcs.h:376
static void BlinkM_setScriptLengthReps(byte addr, byte script_id, byte len, byte reps)
Definition: BlinkM_funcs.h:322
static void BlinkM_writeScriptLine(byte addr, byte script_id, byte pos, byte dur, byte cmd, byte arg1, byte arg2, byte arg3)
Definition: BlinkM_funcs.h:353
static void BlinkM_startPowerWithPins(byte pwrpin, byte gndpin)
Definition: BlinkM_funcs.h:85
static int BlinkM_getInputsO(byte addr)
Definition: BlinkM_funcs.h:410
static void BlinkM_sendCmd(byte addr, byte *cmd, int cmdlen)
Definition: BlinkM_funcs.h:127
static int BlinkM_getAddress(byte addr)
Definition: BlinkM_funcs.h:167
static void BlinkM_beginWithPowerPins(byte pwrpin, byte gndpin)
Definition: BlinkM_funcs.h:112
struct _blinkm_script_line blinkm_script_line
static void BlinkM_setFadeSpeed(byte addr, byte fadespeed)
Definition: BlinkM_funcs.h:215
static void BlinkM_fadeToHSB(byte addr, byte hue, byte saturation, byte brightness)
Definition: BlinkM_funcs.h:246
def callback(req)
Definition: client.py:12
static void BlinkM_startPower()
Definition: BlinkM_funcs.h:99
static void BlinkM_stopPower()
Definition: BlinkM_funcs.h:105
static void BlinkM_scanI2CBus(byte from, byte to, void(*callback)(byte add, byte result))
Definition: BlinkM_funcs.h:60
static void BlinkM_readScriptLine(byte addr, byte script_id, byte pos, blinkm_script_line *script_line)
Definition: BlinkM_funcs.h:335
static void BlinkM_setRGB(byte addr, byte red, byte grn, byte blu)
Definition: BlinkM_funcs.h:257
static void BlinkM_begin()
Definition: BlinkM_funcs.h:42
static int8_t BlinkM_findFirstI2CDevice()
Definition: BlinkM_funcs.h:73
static void BlinkM_fadeToRandomRGB(byte addr, byte rrnd, byte grnd, byte brnd)
Definition: BlinkM_funcs.h:268
static void BlinkM_setStartupParams(byte addr, byte mode, byte script_id, byte reps, byte fadespeed, byte timeadj)
Definition: BlinkM_funcs.h:394
static void BlinkM_beginWithPower()
Definition: BlinkM_funcs.h:121
static void BlinkM_fadeToRGB(byte addr, byte red, byte grn, byte blu)
Definition: BlinkM_funcs.h:235
static void BlinkM_playScript(byte addr, byte script_id, byte reps, byte pos)
Definition: BlinkM_funcs.h:303
static int BlinkM_getVersion(byte addr)
Definition: BlinkM_funcs.h:181
static void BlinkM_fadeToRandomHSB(byte addr, byte hrnd, byte srnd, byte brnd)
Definition: BlinkM_funcs.h:278
static int BlinkM_getInputs(byte addr, byte inputs[])
Definition: BlinkM_funcs.h:426
static int BlinkM_checkAddress(byte addr)
Definition: BlinkM_funcs.h:197


rosserial_arduino
Author(s): Michael Ferguson, Adam Stambler
autogenerated on Mon Jun 10 2019 14:53:34