test in real hardware and motor bugs
This commit is contained in:
parent
143d218760
commit
6f257ebbd8
|
@ -2,8 +2,9 @@
|
||||||
* Ideas/TODO:
|
* Ideas/TODO:
|
||||||
* POT_MIN, POT_MAX as variable with calibration procedure. Drive slowly to both ends until value does not get lower.
|
* POT_MIN, POT_MAX as variable with calibration procedure. Drive slowly to both ends until value does not get lower.
|
||||||
* Motor error checking. Timeout overall (if regulation fails or stuck). Timeout movement (motor is tunring but no change in poti value detected). Move right direction.
|
* Motor error checking. Timeout overall (if regulation fails or stuck). Timeout movement (motor is tunring but no change in poti value detected). Move right direction.
|
||||||
* Relais switching (selection and muting)
|
* Hardware: motorentstörkondensatoren einbauen direkt an motor. 47nF + zu - und zwei 10nF + zu case und - zu case
|
||||||
* MQTT topics
|
* PI Optimieren. aktuell overshoot
|
||||||
|
* Implement knob menu structure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
@ -26,6 +27,7 @@ boolean getSelection(uint8_t pbit);
|
||||||
boolean getMute(uint8_t pbit);
|
boolean getMute(uint8_t pbit);
|
||||||
void setSelectionChannel(uint8_t i, boolean state);
|
void setSelectionChannel(uint8_t i, boolean state);
|
||||||
void setMuteChannel(uint8_t i, boolean state);
|
void setMuteChannel(uint8_t i, boolean state);
|
||||||
|
void publishCurrentSetVolume();
|
||||||
|
|
||||||
#define LEDPIN 9 //PB1 = D9 = Pin15
|
#define LEDPIN 9 //PB1 = D9 = Pin15
|
||||||
Adafruit_NeoPixel leds = Adafruit_NeoPixel(9, LEDPIN, NEO_GRB + NEO_KHZ800);
|
Adafruit_NeoPixel leds = Adafruit_NeoPixel(9, LEDPIN, NEO_GRB + NEO_KHZ800);
|
||||||
|
@ -64,10 +66,6 @@ long last_serialdebug=0;
|
||||||
|
|
||||||
Button button_knob;
|
Button button_knob;
|
||||||
|
|
||||||
boolean button_flag=false; //true if button pressed
|
|
||||||
boolean button_released=true;
|
|
||||||
long last_button_released=0; //last time button has been released (for debounce)
|
|
||||||
|
|
||||||
//Shift Register 595
|
//Shift Register 595
|
||||||
//connections: https://www.arduino.cc/en/tutorial/ShiftOut
|
//connections: https://www.arduino.cc/en/tutorial/ShiftOut
|
||||||
#define SRLATCH PD4 //D4 = PD4
|
#define SRLATCH PD4 //D4 = PD4
|
||||||
|
@ -91,10 +89,11 @@ float encoderMultiplier=4.0;
|
||||||
uint8_t motorspeed=0;
|
uint8_t motorspeed=0;
|
||||||
|
|
||||||
#define PIN_POT A0 //A0 = PC0, reference potentiometer wiper
|
#define PIN_POT A0 //A0 = PC0, reference potentiometer wiper
|
||||||
#define DEADZONE_POTI 5 //maximum allowed error. stop when reached this zone
|
#define DEADZONE_POTI 10 //maximum allowed error. stop when reached this zone
|
||||||
#define POT_MIN 10 //minimum value pot can reach
|
#define POT_MIN 45 //minimum value pot can reach
|
||||||
#define POT_MAX 1010 //maximum value pot can reach
|
#define POT_MAX 950 //maximum value pot can reach
|
||||||
#define POTIFILTER 0.8 //0 to 1. 1 means old value stays forever
|
#define POTIFILTER 0.8 //0 to 1. 1 means old value stays forever
|
||||||
|
#define MAX_MOTOR_PWM 192 //0 to 255. Maximum pwm to output
|
||||||
|
|
||||||
int poti_set; //set value, initial value will be read from poti
|
int poti_set; //set value, initial value will be read from poti
|
||||||
int poti_read=0; //read value from poti
|
int poti_read=0; //read value from poti
|
||||||
|
@ -121,10 +120,11 @@ long last_motorcheck=0;
|
||||||
//#define MOTOR_FAILTIME 500 //in ms. if motor did not turn fox x amount of time at least with MINIMUM_MOTORVEL an error will initiate
|
//#define MOTOR_FAILTIME 500 //in ms. if motor did not turn fox x amount of time at least with MINIMUM_MOTORVEL an error will initiate
|
||||||
//long last_motorTooSlow=0; //typically 0
|
//long last_motorTooSlow=0; //typically 0
|
||||||
|
|
||||||
float motorP=1.0;
|
float motorP=2.0;
|
||||||
float motorI=0.1;
|
float motorI=0.1;
|
||||||
float potidifference_integral=0;
|
float potidifference_integral=0;
|
||||||
#define MOTORI_ANTIWINDUP 32 //maximum value for (potidifference_integral*motorI). time depends on INTERVAL_MOTORCHECK
|
#define MOTORI_ANTIWINDUP 90 //maximum value for (potidifference_integral*motorI). time depends on INTERVAL_MOTORCHECK
|
||||||
|
//Motor starts moving at about speed=80
|
||||||
|
|
||||||
long last_potidifferenceLow=0;
|
long last_potidifferenceLow=0;
|
||||||
#define DEADZONETIMEUNTILREACHED 500 //time [ms] poti read value has to be inside of deadzone to set reachedposition flag (and stop regulating)
|
#define DEADZONETIMEUNTILREACHED 500 //time [ms] poti read value has to be inside of deadzone to set reachedposition flag (and stop regulating)
|
||||||
|
@ -145,7 +145,7 @@ void setup() {
|
||||||
|
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
while (!Serial) {};
|
while (!Serial) {};
|
||||||
Serial.println("Starting");
|
Serial.println("Boot");
|
||||||
|
|
||||||
leds.begin();
|
leds.begin();
|
||||||
leds.clear();
|
leds.clear();
|
||||||
|
@ -158,18 +158,17 @@ void setup() {
|
||||||
|
|
||||||
if (useethernet)
|
if (useethernet)
|
||||||
{
|
{
|
||||||
Serial.println("Setting up ethernet connection via DHCP");
|
Serial.println("trying DHCP");
|
||||||
if (Ethernet.begin(mac) == 0) { // setup ethernet communication using DHCP
|
if (Ethernet.begin(mac) == 0) { // setup ethernet communication using DHCP
|
||||||
useethernet=false;
|
useethernet=false;
|
||||||
//Unable to configure Ethernet using DHCP
|
//Unable to configure Ethernet using DHCP
|
||||||
Serial.println("Unable to configure Ethernet using DHCP");
|
Serial.println("DHCP Err");
|
||||||
delay(200);
|
delay(200);
|
||||||
//for (;;);
|
//for (;;);
|
||||||
|
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
useethernet=true;
|
useethernet=true;
|
||||||
Serial.println("Ethernet configured via DHCP");
|
|
||||||
Serial.print("IP address: ");
|
Serial.print("IP address: ");
|
||||||
Serial.println(Ethernet.localIP());
|
Serial.println(Ethernet.localIP());
|
||||||
Serial.println();
|
Serial.println();
|
||||||
|
@ -184,10 +183,10 @@ void setup() {
|
||||||
//Serial.println(ip);
|
//Serial.println(ip);
|
||||||
|
|
||||||
// setup mqtt client
|
// setup mqtt client
|
||||||
Serial.println("Configuring MQTT");
|
Serial.println("Conf MQTT");
|
||||||
mqttClient.setClient(ethClient);
|
mqttClient.setClient(ethClient);
|
||||||
mqttClient.setServer("10.0.0.1", 1883);
|
mqttClient.setServer("10.0.0.1", 1883);
|
||||||
Serial.println("MQTT configured");
|
Serial.println("MQTT ok");
|
||||||
mqttClient.setCallback(callback);
|
mqttClient.setCallback(callback);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
|
@ -198,6 +197,7 @@ void setup() {
|
||||||
poti_set=analogRead(PIN_POT);
|
poti_set=analogRead(PIN_POT);
|
||||||
|
|
||||||
Serial.println("Ready");
|
Serial.println("Ready");
|
||||||
|
|
||||||
last_send = millis();
|
last_send = millis();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -205,10 +205,11 @@ void setup() {
|
||||||
void reconnect() {
|
void reconnect() {
|
||||||
// Loop until reconnected
|
// Loop until reconnected
|
||||||
if (!mqttClient.connected()) {
|
if (!mqttClient.connected()) {
|
||||||
Serial.print("Attempting MQTT connection...");
|
Serial.print("Connect MQTT ..");
|
||||||
// Attempt to connect
|
// Attempt to connect
|
||||||
if (mqttClient.connect(CLIENT_ID)) {
|
if (mqttClient.connect(CLIENT_ID)) {
|
||||||
Serial.println("connected");
|
Serial.println("connected");
|
||||||
|
publishCurrentSetVolume();
|
||||||
mqttClient.publish("audiomixer/ip", ip.c_str()); //Publish own ip
|
mqttClient.publish("audiomixer/ip", ip.c_str()); //Publish own ip
|
||||||
mqttClient.subscribe("audiomixer/volume/set"); //subscribe to /set, republish without /set
|
mqttClient.subscribe("audiomixer/volume/set"); //subscribe to /set, republish without /set
|
||||||
mqttClient.subscribe("audiomixer/mute/set"); //without range
|
mqttClient.subscribe("audiomixer/mute/set"); //without range
|
||||||
|
@ -221,6 +222,7 @@ void reconnect() {
|
||||||
String sub_topic="audiomixer/select_"+String(i)+"/set";
|
String sub_topic="audiomixer/select_"+String(i)+"/set";
|
||||||
mqttClient.subscribe((char*) sub_topic.c_str());
|
mqttClient.subscribe((char*) sub_topic.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Serial.print("failed, rc=");
|
Serial.print("failed, rc=");
|
||||||
Serial.print(mqttClient.state());
|
Serial.print(mqttClient.state());
|
||||||
|
@ -291,6 +293,7 @@ void loop() {
|
||||||
poti_set+=volEncVel*encoderMultiplier; //change poti set value
|
poti_set+=volEncVel*encoderMultiplier; //change poti set value
|
||||||
poti_set=constrain(poti_set, POT_MIN,POT_MAX);
|
poti_set=constrain(poti_set, POT_MIN,POT_MAX);
|
||||||
poti_reachedposition=false;
|
poti_reachedposition=false;
|
||||||
|
publishCurrentSetVolume();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -371,7 +374,7 @@ void loop() {
|
||||||
potidifference_integral+=potidifference*motorI;
|
potidifference_integral+=potidifference*motorI;
|
||||||
potidifference_integral=constrain(potidifference_integral,-MOTORI_ANTIWINDUP,MOTORI_ANTIWINDUP); //constrain
|
potidifference_integral=constrain(potidifference_integral,-MOTORI_ANTIWINDUP,MOTORI_ANTIWINDUP); //constrain
|
||||||
_motormove=potidifference*motorP+potidifference_integral;
|
_motormove=potidifference*motorP+potidifference_integral;
|
||||||
motorspeed=constrain(abs(_motormove), 0,255);
|
motorspeed=constrain(abs(_motormove), 0,MAX_MOTOR_PWM);
|
||||||
if (poti_read<=POT_MIN && _motormove<0) { //stop motor if soft endstops reached and wants to turn that way
|
if (poti_read<=POT_MIN && _motormove<0) { //stop motor if soft endstops reached and wants to turn that way
|
||||||
MOTOR_STOP();
|
MOTOR_STOP();
|
||||||
potidifference_integral=0;
|
potidifference_integral=0;
|
||||||
|
@ -413,20 +416,19 @@ void loop() {
|
||||||
last_serialdebug=loopmillis;
|
last_serialdebug=loopmillis;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Serial.print(" set=");
|
Serial.print(" set=");
|
||||||
Serial.print(poti_set);
|
Serial.print(poti_set);
|
||||||
Serial.print(" is=");
|
Serial.print(" is=");
|
||||||
Serial.print(poti_read);
|
Serial.print(poti_read);
|
||||||
Serial.print(" motorspeed=");
|
Serial.print(" mspeed=");
|
||||||
Serial.print(motorspeed);
|
Serial.print(motorspeed);
|
||||||
Serial.print(" iValue=");
|
Serial.print(" iVal=");
|
||||||
Serial.print(potidifference_integral);
|
Serial.print(potidifference_integral);
|
||||||
Serial.println("");
|
if (poti_reachedposition) {
|
||||||
|
Serial.print("!");
|
||||||
if (button_flag){ //TODO: remove hier if correct behaviour implemented
|
|
||||||
Serial.println("BUTTON Pressed");
|
|
||||||
button_flag=false; //clear flag to reenable button triggering.
|
|
||||||
}
|
}
|
||||||
|
Serial.println("");
|
||||||
|
|
||||||
for(uint8_t i=0;i<leds.numPixels();i++){ //set color of all leds
|
for(uint8_t i=0;i<leds.numPixels();i++){ //set color of all leds
|
||||||
leds.setPixelColor(i, Wheel(wheelpos+i*10));
|
leds.setPixelColor(i, Wheel(wheelpos+i*10));
|
||||||
|
@ -439,6 +441,10 @@ void loop() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (loopmillis%5001==0) {
|
||||||
|
Serial.println(loopmillis); //alive print. for debugging
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -460,9 +466,8 @@ void sendData() {
|
||||||
void callback(char* topic, byte* payload, unsigned int length) {
|
void callback(char* topic, byte* payload, unsigned int length) {
|
||||||
payload[length] = '\0'; //add end of string character
|
payload[length] = '\0'; //add end of string character
|
||||||
String spayload = String((char*)payload);
|
String spayload = String((char*)payload);
|
||||||
Serial.print("Message arrived [");
|
Serial.print("Message arrived:");
|
||||||
Serial.print(topic);
|
Serial.print(topic);
|
||||||
Serial.print("] ");//MQTT_BROKER
|
|
||||||
for (unsigned int i = 0; i < length; i++) {
|
for (unsigned int i = 0; i < length; i++) {
|
||||||
Serial.print((char)payload[i]);
|
Serial.print((char)payload[i]);
|
||||||
}
|
}
|
||||||
|
@ -480,20 +485,18 @@ void callback(char* topic, byte* payload, unsigned int length) {
|
||||||
|
|
||||||
float _floatvalue = spayload.toFloat();
|
float _floatvalue = spayload.toFloat();
|
||||||
_floatvalue=constrain(_floatvalue,0.0,100.0);
|
_floatvalue=constrain(_floatvalue,0.0,100.0);
|
||||||
Serial.print("Volume string=");
|
/*Serial.print("Volume string=");
|
||||||
Serial.println(spayload);
|
Serial.println(spayload);
|
||||||
Serial.print("setvalue=");
|
Serial.print("setvalue=");
|
||||||
Serial.println(_floatvalue);
|
Serial.println(_floatvalue);*/
|
||||||
|
|
||||||
poti_set=constrain(map(_floatvalue,0.0,100.0,POT_MIN,POT_MAX),POT_MIN,POT_MAX); //set new poti position
|
poti_set=constrain(map(_floatvalue,0.0,100.0,POT_MIN,POT_MAX),POT_MIN,POT_MAX); //set new poti position
|
||||||
poti_reachedposition=false; //aim for new position
|
poti_reachedposition=false; //aim for new position
|
||||||
|
|
||||||
char pub_payload[8]; // Buffer big enough for 7-character float
|
publishCurrentSetVolume();
|
||||||
dtostrf(_floatvalue, 1, 2, pub_payload);
|
|
||||||
mqttClient.publish("audiomixer/volume", pub_payload);
|
|
||||||
|
|
||||||
}else if (String(topic).equals("audiomixer/mute/set")) { //withouth range
|
}else if (String(topic).equals("audiomixer/mute/set")) { //withouth range
|
||||||
Serial.print("Mute string="); Serial.println(spayload);
|
//Serial.print("Mute string="); Serial.println(spayload);
|
||||||
uint16_t ipayload=spayload.toInt();
|
uint16_t ipayload=spayload.toInt();
|
||||||
if (spayload.equalsIgnoreCase("false")) {
|
if (spayload.equalsIgnoreCase("false")) {
|
||||||
setMuteInt(0); //all unmuted
|
setMuteInt(0); //all unmuted
|
||||||
|
@ -515,7 +518,7 @@ void callback(char* topic, byte* payload, unsigned int length) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}else if (String(topic).startsWith("audiomixer/mute_")) { //with range
|
}else if (String(topic).startsWith("audiomixer/mute_")) { //with range
|
||||||
Serial.print("Mute range string="); Serial.println(spayload);
|
//Serial.print("Mute range string="); Serial.println(spayload);
|
||||||
uint8_t _index=255;
|
uint8_t _index=255;
|
||||||
for (uint8_t i=0; i<NUMMUTECHANNELS && _index==255; i++) {
|
for (uint8_t i=0; i<NUMMUTECHANNELS && _index==255; i++) {
|
||||||
if (String(topic).equals("audiomixer/mute_"+String(i)+"/set")) {
|
if (String(topic).equals("audiomixer/mute_"+String(i)+"/set")) {
|
||||||
|
@ -537,7 +540,7 @@ void callback(char* topic, byte* payload, unsigned int length) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}else if (String(topic).equals("audiomixer/select/set")) { //withouth range
|
}else if (String(topic).equals("audiomixer/select/set")) { //withouth range
|
||||||
Serial.print("Select string="); Serial.println(spayload);
|
//Serial.print("Select string="); Serial.println(spayload);
|
||||||
uint16_t ipayload=spayload.toInt();
|
uint16_t ipayload=spayload.toInt();
|
||||||
if (spayload.equalsIgnoreCase("false")) {
|
if (spayload.equalsIgnoreCase("false")) {
|
||||||
setSelectionInt(0); //all select to NC
|
setSelectionInt(0); //all select to NC
|
||||||
|
@ -559,14 +562,14 @@ void callback(char* topic, byte* payload, unsigned int length) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}else if (String(topic).startsWith("audiomixer/select_")) {
|
}else if (String(topic).startsWith("audiomixer/select_")) {
|
||||||
Serial.print("Select string="); Serial.println(spayload);
|
//Serial.print("Select string="); Serial.println(spayload);
|
||||||
uint8_t _index=255;
|
uint8_t _index=255;
|
||||||
for (uint8_t i=0; i<NUMSELECTCHANNELS && _index==255; i++) {
|
for (uint8_t i=0; i<NUMSELECTCHANNELS && _index==255; i++) {
|
||||||
if (String(topic).equals("audiomixer/select_"+String(i)+"/set")) {
|
if (String(topic).equals("audiomixer/select_"+String(i)+"/set")) {
|
||||||
_index=i;
|
_index=i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Serial.print("Found index:"); Serial.println(_index);
|
//Serial.print("Found index:"); Serial.println(_index);
|
||||||
if (_index==255) {
|
if (_index==255) {
|
||||||
Serial.println("Index out of range");
|
Serial.println("Index out of range");
|
||||||
}else{ //index ok
|
}else{ //index ok
|
||||||
|
@ -622,7 +625,6 @@ void setMuteInt(uint8_t i) {
|
||||||
uint16_t mask=(( (uint16_t)1<<(NUMMUTECHANNELS))-1 )<<NUMSELECTCHANNELS;
|
uint16_t mask=(( (uint16_t)1<<(NUMMUTECHANNELS))-1 )<<NUMSELECTCHANNELS;
|
||||||
srbits = ((i<<NUMSELECTCHANNELS) & mask) | (srbits & ~mask);
|
srbits = ((i<<NUMSELECTCHANNELS) & mask) | (srbits & ~mask);
|
||||||
srShiftOut();
|
srShiftOut();
|
||||||
Serial.println(srbits);
|
|
||||||
}
|
}
|
||||||
boolean getMute(uint8_t pbit) {
|
boolean getMute(uint8_t pbit) {
|
||||||
return srbits & (1<<(pbit+NUMSELECTCHANNELS)); //check bit at position
|
return srbits & (1<<(pbit+NUMSELECTCHANNELS)); //check bit at position
|
||||||
|
@ -647,3 +649,12 @@ void setMuteChannel(uint8_t i, boolean state){
|
||||||
srWrite(i+NUMSELECTCHANNELS, state); //offset. selection is first shift register
|
srWrite(i+NUMSELECTCHANNELS, state); //offset. selection is first shift register
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void publishCurrentSetVolume()
|
||||||
|
{
|
||||||
|
float _setpercentage=map(poti_set,POT_MIN,POT_MAX, 0.0,100.0); //get percentage from set poti value
|
||||||
|
char pub_payload[8]; // Buffer big enough for 7-character float
|
||||||
|
dtostrf(_setpercentage, 1, 2, pub_payload);
|
||||||
|
mqttClient.publish("audiomixer/volume", pub_payload);
|
||||||
|
Serial.print("pub="); Serial.println(_setpercentage);
|
||||||
|
}
|
Loading…
Reference in New Issue