-
Notifications
You must be signed in to change notification settings - Fork 30
/
_P022_PCA9685.ino
120 lines (104 loc) · 3.94 KB
/
_P022_PCA9685.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
//#######################################################################################################
//#################################### Plugin 022: PCA9685 ##############################################
//#######################################################################################################
#define PLUGIN_022
#define PLUGIN_ID_022 22
#define PLUGIN_NAME_022 "PWM - PCA9685"
#define PLUGIN_VALUENAME1_022 "PWM"
#define PCA9685_MODE1 0x00 // location for Mode1 register address
#define PCA9685_MODE2 0x01 // location for Mode2 reigster address
#define PCA9685_LED0 0x06 // location for start of LED0 registers
#define PCA9685_ADDRESS 0x40 // I2C address
boolean Plugin_022_init = false;
boolean Plugin_022(byte function, struct EventStruct *event, String& string)
{
boolean success = false;
static byte switchstate[TASKS_MAX];
switch (function)
{
case PLUGIN_DEVICE_ADD:
{
Device[++deviceCount].Number = PLUGIN_ID_022;
Device[deviceCount].Type = DEVICE_TYPE_I2C;
Device[deviceCount].VType = SENSOR_TYPE_SINGLE;
Device[deviceCount].Ports = 0;
Device[deviceCount].PullUpOption = false;
Device[deviceCount].InverseLogicOption = false;
Device[deviceCount].FormulaOption = false;
Device[deviceCount].ValueCount = 0;
Device[deviceCount].Custom = true;
Device[deviceCount].TimerOption = false;
break;
}
case PLUGIN_GET_DEVICENAME:
{
string = F(PLUGIN_NAME_022);
break;
}
case PLUGIN_GET_DEVICEVALUENAMES:
{
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_022));
break;
}
case PLUGIN_WRITE:
{
String log = "";
String command = parseString(string, 1);
if (command == F("pcapwm"))
{
if (!Plugin_022_init) Plugin_022_initialize();
success = true;
Plugin_022_Write(event->Par1, event->Par2);
setPinState(PLUGIN_ID_022, event->Par1, PIN_MODE_PWM, event->Par2);
log = String(F("PCA : GPIO ")) + String(event->Par1) + String(F(" Set PWM to ")) + String(event->Par2);
addLog(LOG_LEVEL_INFO, log);
SendStatus(event->Source, getPinStateJSON(SEARCH_PIN_STATE, PLUGIN_ID_022, event->Par1, log, 0));
}
if (command == F("status"))
{
if (parseString(string, 2) == F("pca"))
{
if (!Plugin_022_init) Plugin_022_initialize();
success = true;
SendStatus(event->Source, getPinStateJSON(SEARCH_PIN_STATE, PLUGIN_ID_022, event->Par2, dummyString, 0));
}
}
break;
}
}
return success;
}
//********************************************************************************
// PCA9685 config
//********************************************************************************
void Plugin_022_writeRegister(int regAddress, byte data) {
Wire.beginTransmission(PCA9685_ADDRESS);
Wire.write(regAddress);
Wire.write(data);
Wire.endTransmission();
}
//********************************************************************************
// PCA9685 write
//********************************************************************************
boolean Plugin_022_Write(byte Par1, int Par2)
{
boolean success = false;
uint16_t LED_ON = 0;
uint16_t LED_OFF = Par2;
Wire.beginTransmission(PCA9685_ADDRESS);
Wire.write(0x06 + 4 * Par1);
Wire.write(lowByte(LED_ON));
Wire.write(highByte(LED_ON));
Wire.write(lowByte(LED_OFF));
Wire.write(highByte(LED_OFF));
Wire.endTransmission();
}
void Plugin_022_initialize()
{
// default mode is open drain ouput, drive leds connected to VCC
Plugin_022_writeRegister(PCA9685_MODE1, (byte)0x01); // reset the device
delay(1);
Plugin_022_writeRegister(PCA9685_MODE1, (byte)B10100000); // set up for auto increment
Plugin_022_writeRegister(PCA9685_MODE2, (byte)0x10); // set to output
Plugin_022_init = true;
}