diff --git a/solarpump/sayNumber.h b/solarpump/sayNumber.h new file mode 100644 index 0000000000000000000000000000000000000000..38404c6613727a5638efe7e443f583afbf944176 --- /dev/null +++ b/solarpump/sayNumber.h @@ -0,0 +1,7 @@ +#ifndef SAYNUMBERS_H +#define SAYNUMBERS_H + +void sayNumber(int32_t number); +void sayNumber(double number, uint8_t roundDigits); + +#endif diff --git a/solarpump/sayNumber.ino b/solarpump/sayNumber.ino new file mode 100644 index 0000000000000000000000000000000000000000..bfd3846084cff656d4c93f9f21aff1896a2f00e5 --- /dev/null +++ b/solarpump/sayNumber.ino @@ -0,0 +1,156 @@ +#include "mp3.h" +#include "soundFiles.h" + +// says the digit +static void sayDigit(int8_t number) { + switch (number) { + case 0: + playFileQueue(SOUND_NULL); + break; + case 1: + playFileQueue(SOUND_EINS); + break; + case 2: + playFileQueue(SOUND_ZWEI); + break; + case 3: + playFileQueue(SOUND_DREI); + break; + case 4: + playFileQueue(SOUND_VIER); + break; + case 5: + playFileQueue(SOUND_FUNF); + break; + case 6: + playFileQueue(SOUND_SECHS); + break; + case 7: + playFileQueue(SOUND_SIEBEN); + break; + case 8: + playFileQueue(SOUND_ACHT); + break; + case 9: + playFileQueue(SOUND_NEUN); + break; + default: + break; + } +} + +// Same as sayNumber(int32_t n) only for 1 it says EIN instead of EINS. +static void sayPreNumber(int32_t number) { + if (number == 1) + playFileQueue(SOUND_EIN); + else + sayNumber(number); +} + +// Same as sayNumber(int32_t n) only for 0 it does nothing +static void sayAftNumber(int32_t number) { + if (number) + sayNumber(number); +} + +// say integer number +void sayNumber(int32_t number) { + // Negative numbers are spoken the same way as positive numbers only with "Minus" at the beginning. + if (number < 0) { + playFileQueue(SOUND_MINUS); + sayNumber(-number); + // 1-digit numbers + } else if (number < 10) { + sayDigit(number); + // 2-digit numbers + } else if (number < 100) { + // extra cases for 11 and 12 + switch (number) { + case 11: + playFileQueue(SOUND_ELF); + break; + case 12: + playFileQueue(SOUND_ZWOLF); + break; + default: + // German specific: Say the 1-digit first, then the 10-digit + int32_t tens = number / 10; + int32_t ones = number - 10 * tens; + // first say the 1-digit + if (ones) { + sayPreNumber(ones); + // UND only for numbers > 20. (VierUNDzwanzig, but not VierUNDzehn.) + if (tens >= 2) + playFileQueue(SOUND_UND); + } + // then say the 10-digit + switch (tens) { + case 1: + playFileQueue(SOUND_ZEHN); + break; + case 2: + playFileQueue(SOUND_ZWANZIG); + break; + case 3: + playFileQueue(SOUND_DREISSIG); + break; + case 4: + playFileQueue(SOUND_VIERZIG); + break; + case 5: + playFileQueue(SOUND_FUNFZIG); + break; + case 6: + playFileQueue(SOUND_SECHZIG); + break; + case 7: + playFileQueue(SOUND_SIEBZIG); + break; + case 8: + playFileQueue(SOUND_ACHTZIG); + break; + case 9: + playFileQueue(SOUND_NEUNZIG); + break; + default: + break; + } + break; + } + // 3-digit numbers + } else { + int32_t hundreds = number / 100; + sayPreNumber(hundreds); + playFileQueue(SOUND_HUNDERT); + sayAftNumber(number - 100 * hundreds); + } +} + +/* + * Say any number in the int-range between -999999 and 999999 (in German) + * double n: The number to say + * uint8_t roundDigits: How many digits after the comma should be said (last one will get rounded) + * Example: sayNumber(34.236, 2) will say "Vierunddreißig Komma Zwei Vier" + */ +void sayNumber(double number, uint8_t roundDigits) { + // do the rounding at the correct digit + number = round(number * pow(10, roundDigits)) / pow(10, roundDigits); + // say the pre-decimal digits + int32_t int_n = (int32_t)number; + sayNumber(int_n); + // say the decimals + if (roundDigits) { + number = abs(number - int_n); + playFileQueue(SOUND_KOMMA); + for (int8_t digit = 1; digit <= roundDigits; ++digit) { + double d_newDigit = number * pow(10, digit) - 10 * (int32_t)(number * pow(10, digit-1)); + int8_t newDigit; + // round correctly for the last digit + if (digit == roundDigits) + newDigit = (int8_t)round(d_newDigit); + else + newDigit = (int8_t)d_newDigit; + sayDigit(newDigit); + } + } +} diff --git a/solarpump/solarpump.ino b/solarpump/solarpump.ino index bf814fa9a0246768aae80b8bd5e6db822e253d37..406e11720ed34792c682ba274b1e7a66c58f938d 100644 --- a/solarpump/solarpump.ino +++ b/solarpump/solarpump.ino @@ -3,6 +3,7 @@ #include "temperature.h" #include "mp3.h" #include "soundFiles.h" +#include "sayNumber.h" #include <LiquidCrystal_I2C.h> // LCD display at address 0x27 with 16 columns and 2 rows @@ -190,6 +191,7 @@ void loop(void) { playFileQueue(SOUND_TEMPERATURE); playFileQueue(SOUND_HOCHSTER_WERT); playFileQueue(SOUND_KOMMA); + sayNumber(14); } else { displayLight(false); }