mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-07-27 19:57:38 +00:00
implemented speaker plugin from http://www.letscontrolit.com/forum/viewtopic.php?f=4&t=343&hilit=speaker&start=10
This commit is contained in:
@@ -1327,7 +1327,7 @@ String parseTemplate(String &tmpString, byte lineSize)
|
||||
newString.replace("%ip%", strIP);
|
||||
|
||||
newString.replace("%sysload%", String(100 - (100 * loopCounterLast / loopCounterMax)));
|
||||
|
||||
|
||||
// padding spaces
|
||||
while (newString.length() < lineSize)
|
||||
newString += " ";
|
||||
@@ -2244,3 +2244,177 @@ void createRuleEvents(byte TaskIndex)
|
||||
rulesProcessing(eventString);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef PLUGIN_BUILD_TESTING
|
||||
|
||||
#define isdigit(n) (n >= '0' && n <= '9')
|
||||
|
||||
/********************************************************************************************\
|
||||
Generate a tone of specified frequency on pin
|
||||
\*********************************************************************************************/
|
||||
void tone(uint8_t _pin, unsigned int frequency, unsigned long duration) {
|
||||
analogWriteFreq(frequency);
|
||||
analogWrite(_pin,100);
|
||||
delay(duration);
|
||||
analogWrite(_pin,0);
|
||||
}
|
||||
|
||||
/********************************************************************************************\
|
||||
Play RTTTL string on specified pin
|
||||
\*********************************************************************************************/
|
||||
void play_rtttl(uint8_t _pin, char *p )
|
||||
{
|
||||
#define OCTAVE_OFFSET 0
|
||||
// Absolutely no error checking in here
|
||||
|
||||
int notes[] = { 0,
|
||||
262, 277, 294, 311, 330, 349, 370, 392, 415, 440, 466, 494,
|
||||
523, 554, 587, 622, 659, 698, 740, 784, 831, 880, 932, 988,
|
||||
1047, 1109, 1175, 1245, 1319, 1397, 1480, 1568, 1661, 1760, 1865, 1976,
|
||||
2093, 2217, 2349, 2489, 2637, 2794, 2960, 3136, 3322, 3520, 3729, 3951
|
||||
};
|
||||
|
||||
|
||||
|
||||
byte default_dur = 4;
|
||||
byte default_oct = 6;
|
||||
int bpm = 63;
|
||||
int num;
|
||||
long wholenote;
|
||||
long duration;
|
||||
byte note;
|
||||
byte scale;
|
||||
|
||||
// format: d=N,o=N,b=NNN:
|
||||
// find the start (skip name, etc)
|
||||
|
||||
while(*p != ':') p++; // ignore name
|
||||
p++; // skip ':'
|
||||
|
||||
// get default duration
|
||||
if(*p == 'd')
|
||||
{
|
||||
p++; p++; // skip "d="
|
||||
num = 0;
|
||||
while(isdigit(*p))
|
||||
{
|
||||
num = (num * 10) + (*p++ - '0');
|
||||
}
|
||||
if(num > 0) default_dur = num;
|
||||
p++; // skip comma
|
||||
}
|
||||
|
||||
// get default octave
|
||||
if(*p == 'o')
|
||||
{
|
||||
p++; p++; // skip "o="
|
||||
num = *p++ - '0';
|
||||
if(num >= 3 && num <=7) default_oct = num;
|
||||
p++; // skip comma
|
||||
}
|
||||
|
||||
// get BPM
|
||||
if(*p == 'b')
|
||||
{
|
||||
p++; p++; // skip "b="
|
||||
num = 0;
|
||||
while(isdigit(*p))
|
||||
{
|
||||
num = (num * 10) + (*p++ - '0');
|
||||
}
|
||||
bpm = num;
|
||||
p++; // skip colon
|
||||
}
|
||||
|
||||
// BPM usually expresses the number of quarter notes per minute
|
||||
wholenote = (60 * 1000L / bpm) * 4; // this is the time for whole note (in milliseconds)
|
||||
|
||||
// now begin note loop
|
||||
while(*p)
|
||||
{
|
||||
// first, get note duration, if available
|
||||
num = 0;
|
||||
while(isdigit(*p))
|
||||
{
|
||||
num = (num * 10) + (*p++ - '0');
|
||||
}
|
||||
|
||||
if (num) duration = wholenote / num;
|
||||
else duration = wholenote / default_dur; // we will need to check if we are a dotted note after
|
||||
|
||||
// now get the note
|
||||
note = 0;
|
||||
|
||||
switch(*p)
|
||||
{
|
||||
case 'c':
|
||||
note = 1;
|
||||
break;
|
||||
case 'd':
|
||||
note = 3;
|
||||
break;
|
||||
case 'e':
|
||||
note = 5;
|
||||
break;
|
||||
case 'f':
|
||||
note = 6;
|
||||
break;
|
||||
case 'g':
|
||||
note = 8;
|
||||
break;
|
||||
case 'a':
|
||||
note = 10;
|
||||
break;
|
||||
case 'b':
|
||||
note = 12;
|
||||
break;
|
||||
case 'p':
|
||||
default:
|
||||
note = 0;
|
||||
}
|
||||
p++;
|
||||
|
||||
// now, get optional '#' sharp
|
||||
if(*p == '#')
|
||||
{
|
||||
note++;
|
||||
p++;
|
||||
}
|
||||
|
||||
// now, get optional '.' dotted note
|
||||
if(*p == '.')
|
||||
{
|
||||
duration += duration/2;
|
||||
p++;
|
||||
}
|
||||
|
||||
// now, get scale
|
||||
if(isdigit(*p))
|
||||
{
|
||||
scale = *p - '0';
|
||||
p++;
|
||||
}
|
||||
else
|
||||
{
|
||||
scale = default_oct;
|
||||
}
|
||||
|
||||
scale += OCTAVE_OFFSET;
|
||||
|
||||
if(*p == ',')
|
||||
p++; // skip comma for next note (or we may be at the end)
|
||||
|
||||
// now play the note
|
||||
if(note)
|
||||
{
|
||||
tone(_pin, notes[(scale - 4) * 12 + note], duration);
|
||||
}
|
||||
else
|
||||
{
|
||||
delay(duration/10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
|
||||
#define BUILD_GIT "(unknown)"
|
||||
#define BUILD_GIT "v1.1.0-beta6-1-g5361de6"
|
||||
|
||||
+39
-6
@@ -6,7 +6,6 @@
|
||||
#define PLUGIN_ID_001 1
|
||||
#define PLUGIN_NAME_001 "Switch input"
|
||||
#define PLUGIN_VALUENAME1_001 "Switch"
|
||||
|
||||
boolean Plugin_001(byte function, struct EventStruct *event, String& string)
|
||||
{
|
||||
boolean success = false;
|
||||
@@ -137,7 +136,7 @@ boolean Plugin_001(byte function, struct EventStruct *event, String& string)
|
||||
|
||||
switchstate[event->TaskIndex] = digitalRead(Settings.TaskDevicePin1[event->TaskIndex]);
|
||||
outputstate[event->TaskIndex] = switchstate[event->TaskIndex];
|
||||
|
||||
|
||||
// if boot state must be send, inverse default state
|
||||
if (Settings.TaskDevicePluginConfig[event->TaskIndex][3])
|
||||
{
|
||||
@@ -225,17 +224,51 @@ boolean Plugin_001(byte function, struct EventStruct *event, String& string)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PLUGIN_BUILD_TESTING
|
||||
|
||||
if (command == F("rtttl"))
|
||||
{
|
||||
success = true;
|
||||
if (event->Par1 >= 0 && event->Par1 <= 16)
|
||||
{
|
||||
pinMode(event->Par1, OUTPUT);
|
||||
char sng[1024] ="";
|
||||
string.replace("-","#");
|
||||
string.toCharArray(sng, 1024);
|
||||
play_rtttl(event->Par1, sng);
|
||||
setPinState(PLUGIN_ID_001, event->Par1, PIN_MODE_OUTPUT, event->Par2);
|
||||
log = String(F("SW : ")) + string;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
SendStatus(event->Source, getPinStateJSON(SEARCH_PIN_STATE, PLUGIN_ID_001, event->Par1, log, 0));
|
||||
}
|
||||
}
|
||||
|
||||
if (command == F("tone"))
|
||||
{
|
||||
success = true;
|
||||
if (event->Par1 >= 0 && event->Par1 <= 16)
|
||||
{
|
||||
pinMode(event->Par1, OUTPUT);
|
||||
tone(event->Par1, event->Par2, event->Par3);
|
||||
setPinState(PLUGIN_ID_001, event->Par1, PIN_MODE_OUTPUT, event->Par2);
|
||||
log = String(F("SW : ")) + string;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
SendStatus(event->Source, getPinStateJSON(SEARCH_PIN_STATE, PLUGIN_ID_001, event->Par1, log, 0));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (command == F("pwm"))
|
||||
{
|
||||
success = true;
|
||||
if (event->Par1 >= 0 && event->Par1 <= 16)
|
||||
{
|
||||
pinMode(event->Par1, OUTPUT);
|
||||
|
||||
|
||||
if(event->Par3 != 0)
|
||||
{
|
||||
byte prev_mode;
|
||||
uint16_t prev_value;
|
||||
uint16_t prev_value;
|
||||
getPinState(PLUGIN_ID_001, event->Par1, &prev_mode, &prev_value);
|
||||
if(prev_mode != PIN_MODE_PWM)
|
||||
prev_value = 0;
|
||||
@@ -251,7 +284,7 @@ boolean Plugin_001(byte function, struct EventStruct *event, String& string)
|
||||
delay(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
analogWrite(event->Par1, event->Par2);
|
||||
setPinState(PLUGIN_ID_001, event->Par1, PIN_MODE_PWM, event->Par2);
|
||||
log = String(F("SW : GPIO ")) + String(event->Par1) + String(F(" Set PWM to ")) + String(event->Par2);
|
||||
@@ -339,4 +372,4 @@ boolean Plugin_001(byte function, struct EventStruct *event, String& string)
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user