The battery is a 12 V led battery for mopeds.
Yes, I have a DMM and I'm about to use it to record all currents and voltages.
It's kind of in a breadboard stage, where I can disconnect everything. Only thing glued are the servos. One critical connection might be the servo sockets, which are connected to the pins of the PCA9685 driver, just because the driver has these matching pins. The driver not only provides the signal for each servo, but also the power. It is kind of a stupid design that the servos have these sockets with GND, VIN and Signal, when the GND and VIN should be soldered to the power source.
I have the whole thing at my work. I can't do anything before Sunday, but I will post more pictures as soon as I get there.
Right now I'm already very thankful for the help. First of all I'm going to measure currents and voltages.
The project is a mechanical glockenspiel. Two mallets are hitting the glockenspiel bars, playing 2 part melodies. It all works very well already, except for the one servo hanging up. One mallet is attached to a servo, which makes the vertical strike. This servo is glued onto another servo, which moves the mallet horizontally, aiming for the right glockenspiel bar. An Arduino Leonardo reads midi data from a computer and makes the mallets act accordingly.
Here's the code:
#include <frequencyToNote.h>
#include <MIDIUSB.h>
#include <MIDIUSB_Defs.h>
#include <pitchToFrequency.h>
#include <pitchToNote.h>
#include "PCA9685.h"
uint16_t angles[2][25][3] =
{
{ // Bass
// horiz, vertic upper, vertic lower
{ 190, 224, 203 },
{ 204, 222, 205 },
{ 217, 227, 206 },
{ 230, 227, 206 },
{ 241, 227, 206 },
{ 254, 227, 207 },
{ 264, 227, 206 },
{ 276, 227, 206 },
{ 289, 227, 206 },
{ 301, 227, 206 },
{ 311, 227, 204 },
{ 323, 227, 204 },
{ 336, 227, 204 },
{ 349, 227, 204 },
{ 362, 227, 205 },
{ 374, 227, 204 },
{ 384, 227, 206 },
{ 397, 227, 206 },
{ 411, 227, 204 },
{ 421, 227, 204 },
{ 428, 227, 206 },
{ 432, 227, 206 },
{ 443, 227, 206 },
{ 450, 227, 206 },
{ 450, 227, 206 },
},
{ // Discant
// horiz, vertic upper, vertic lower
{ 164, 278, 290 },
{ 164, 278, 290 },
{ 177, 278, 290 },
{ 189, 278, 290 },
{ 203, 278, 290 },
{ 213, 278, 290 },
{ 227, 278, 290 },
{ 237, 278, 290 },
{ 250, 278, 290 },
{ 265, 270, 289 },
{ 276, 278, 290 },
{ 290, 278, 290 },
{ 307, 278, 290 },
{ 320, 274, 288 },
{ 336, 274, 287 },
{ 348, 278, 290 },
{ 362, 278, 290 },
{ 377, 278, 290 },
{ 392, 278, 290 },
{ 406, 278, 289 },
{ 421, 278, 290 },
{ 436, 278, 290 },
{ 451, 277, 287 },
{ 466, 275, 286 },
{ 480, 278, 290 },
}
};
bool blinker = true;
unsigned long t0 = millis();
int8_t isConnected = 0;
PCA9685 *servobank;
struct my_event
{
uint32_t tst;
int np;
int mallet;
};
#define my_delay 200
#define queuelen 5
my_event queue[queuelen];
int queuepush = 0;
int queuepop = 0;
int horiz_servo[2] = { 12, 14 }; // Bass, discant
int vertic_servo[2] = { 13, 15 }; // Bass, discant
// -----------------------------------------------------------------------------
// G4 to G6, midi nr 67 to 91
// -----------------------------------------------------------------------------
void noteOn(byte channel, byte pitch, byte velocity)
{
uint32_t tst;
tst = millis();
int np;
int mallet;
// Blink
digitalWrite(13, blinker);
blinker = !blinker;
np = pitch - 67;
if (np >= 0 && np < 24)
{
if (velocity)
{
if (channel == 0) // diskant
mallet = 1;
else
mallet = 0;
// At note on event, move horizontal servo to place,
// as well as vertical servo to upper position
servobank->setPWM(horiz_servo[mallet], angles[mallet][np][0]);
servobank->setPWM(vertic_servo[mallet], angles[mallet][np][1]);
// If velocity is 1, the mallet is supposed to move to place,
// but not hit the key. To be used to avoid collision of mallets.
// If velocity is > 1, place the event in a queue.
if (velocity > 1)
{
queue[queuepush].tst = tst; // Time stamp
queue[queuepush].np = np; // # of key
queue[queuepush].mallet = mallet; // Discant or bass (1 or 0)
queuepush++;
queuepush %= queuelen;
}
}
}
}
void noteOff(byte channel, byte pitch, byte velocity)
{
}
void controlChange(byte channel, byte control, byte value)
{
}
void setup()
{
Serial.begin(115200);
Serial.println("Me too...");
servobank = new PCA9685(0x40);
servobank->begin();
servobank->setFrequency(50, 0);
for (int i = 0; i < 10; i++)
{
digitalWrite(13, HIGH);
delay(300);
digitalWrite(13, LOW);
delay(300);
}
delay(500);
pinMode(LED_BUILTIN, OUTPUT);
}
bool blynker = false;
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void loop() {
int toggler = 0;
midiEventPacket_t rx;
rx = MidiUSB.read();
switch (rx.header)
{
case 0:
if (queuepop != queuepush)
{
if (millis() - queue[queuepop].tst > my_delay)
{
servobank->setPWM(vertic_servo[queue[queuepop].mallet],
angles[queue[queuepop].mallet][queue[queuepop].np][2]);
queuepop++;
queuepop %= queuelen;
}
}
break; //
case 0x9:
noteOn(
rx.byte1 & 0xF, //channel
rx.byte2, //pitch
rx.byte3 //velocity
);
digitalWrite(LED_BUILTIN, blynker);
blynker = !blynker;
break;
case 0x8:
noteOff(
rx.byte1 & 0xF, //channel
rx.byte2, //pitch
rx.byte3 //velocity
);
break;
case 0xB:
controlChange(
rx.byte1 & 0xF, //channel
rx.byte2, //control
rx.byte3 //value
);
break;
}
}