ADC broken in 1.53?

Qar

Member
I used 1.8.12 with 1.51 for my sketch using a slightliy modified adc dma timer. For Teensy 4.1 support I updated on 1.8.13 and 1.53. There i get the error message that didn't occur before:

"undefined reference to `AnalogBufferDMA::init"

Also tried the pedvide/ADC from github, but it didn't change anything.

Code:
Arduino: 1.8.13 (Windows 10), TD: 1.53, Board: "Teensy 4.1, Serial, 600 MHz, Faster, US English"





















C:\zzz\arduino-1.8.13 unmodded\arduino-builder -dump-prefs -logger=machine -hardware C:\zzz\arduino-1.8.13 unmodded\hardware -hardware C:\Users\b\AppData\Local\Arduino15\packages -tools C:\zzz\arduino-1.8.13 unmodded\tools-builder -tools C:\zzz\arduino-1.8.13 unmodded\hardware\tools\avr -tools C:\Users\b\AppData\Local\Arduino15\packages -built-in-libraries C:\zzz\arduino-1.8.13 unmodded\libraries -libraries C:\Users\b\Documents\Arduino\libraries -fqbn=teensy:avr:teensy41:usb=serial,speed=600,opt=o2std,keys=en-us -ide-version=10813 -build-path C:\Users\b\AppData\Local\Temp\arduino_build_696557 -warnings=default -build-cache C:\Users\b\AppData\Local\Temp\arduino_cache_303420 -verbose C:\Users\b\Dropbox\Arduino\a\H2Regulation\H2Regulation.ino

C:\zzz\arduino-1.8.13 unmodded\arduino-builder -compile -logger=machine -hardware C:\zzz\arduino-1.8.13 unmodded\hardware -hardware C:\Users\b\AppData\Local\Arduino15\packages -tools C:\zzz\arduino-1.8.13 unmodded\tools-builder -tools C:\zzz\arduino-1.8.13 unmodded\hardware\tools\avr -tools C:\Users\b\AppData\Local\Arduino15\packages -built-in-libraries C:\zzz\arduino-1.8.13 unmodded\libraries -libraries C:\Users\b\Documents\Arduino\libraries -fqbn=teensy:avr:teensy41:usb=serial,speed=600,opt=o2std,keys=en-us -ide-version=10813 -build-path C:\Users\b\AppData\Local\Temp\arduino_build_696557 -warnings=default -build-cache C:\Users\b\AppData\Local\Temp\arduino_cache_303420 -verbose C:\Users\b\Dropbox\Arduino\a\H2Regulation\H2Regulation.ino

Using board 'teensy41' from platform in folder: C:\zzz\arduino-1.8.13 unmodded\hardware\teensy\avr

Using core 'teensy4' from platform in folder: C:\zzz\arduino-1.8.13 unmodded\hardware\teensy\avr

Detecting libraries used...

"C:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=153 -DARDUINO=10813 -DARDUINO_TEENSY41 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\cores\\teensy4" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\sketch\\H2Regulation.ino.cpp" -o nul -DARDUINO_LIB_DISCOVERY_PHASE

Alternatives for ADC.h: [ADC@8.0]

ResolveLibrary(ADC.h)

  -> candidates: [ADC@8.0]

"C:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=153 -DARDUINO=10813 -DARDUINO_TEENSY41 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\cores\\teensy4" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\ADC" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\sketch\\H2Regulation.ino.cpp" -o nul -DARDUINO_LIB_DISCOVERY_PHASE

Alternatives for ILI9341_t3.h: [ILI9341_t3@1.0]

ResolveLibrary(ILI9341_t3.h)

  -> candidates: [ILI9341_t3@1.0]

"C:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=153 -DARDUINO=10813 -DARDUINO_TEENSY41 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\cores\\teensy4" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\ADC" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\ILI9341_t3" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\sketch\\H2Regulation.ino.cpp" -o nul -DARDUINO_LIB_DISCOVERY_PHASE

Alternatives for SPI.h: [SPI@1.0]

ResolveLibrary(SPI.h)

  -> candidates: [SPI@1.0]

"C:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=153 -DARDUINO=10813 -DARDUINO_TEENSY41 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\cores\\teensy4" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\ADC" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\ILI9341_t3" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\SPI" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\sketch\\H2Regulation.ino.cpp" -o nul -DARDUINO_LIB_DISCOVERY_PHASE

Alternatives for SdFat.h: [SdFat-beta-master@2.0.0-beta.8]

ResolveLibrary(SdFat.h)

  -> candidates: [SdFat-beta-master@2.0.0-beta.8]

"C:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=153 -DARDUINO=10813 -DARDUINO_TEENSY41 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\cores\\teensy4" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\ADC" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\ILI9341_t3" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\SPI" "-IC:\\Users\\b\\Documents\\Arduino\\libraries\\SdFat-beta-master\\src" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\sketch\\H2Regulation.ino.cpp" -o nul -DARDUINO_LIB_DISCOVERY_PHASE

Alternatives for XPT2046_Touchscreen.h: [XPT2046_Touchscreen@1.3]

ResolveLibrary(XPT2046_Touchscreen.h)

  -> candidates: [XPT2046_Touchscreen@1.3]

"C:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=153 -DARDUINO=10813 -DARDUINO_TEENSY41 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\cores\\teensy4" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\ADC" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\ILI9341_t3" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\SPI" "-IC:\\Users\\b\\Documents\\Arduino\\libraries\\SdFat-beta-master\\src" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\XPT2046_Touchscreen" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\sketch\\H2Regulation.ino.cpp" -o nul -DARDUINO_LIB_DISCOVERY_PHASE

Alternatives for MCP4728.h: [MCP4728-master@0.1.0]

ResolveLibrary(MCP4728.h)

  -> candidates: [MCP4728-master@0.1.0]

"C:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=153 -DARDUINO=10813 -DARDUINO_TEENSY41 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\cores\\teensy4" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\ADC" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\ILI9341_t3" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\SPI" "-IC:\\Users\\b\\Documents\\Arduino\\libraries\\SdFat-beta-master\\src" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\XPT2046_Touchscreen" "-IC:\\Users\\b\\Documents\\Arduino\\libraries\\MCP4728-master" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\sketch\\H2Regulation.ino.cpp" -o nul -DARDUINO_LIB_DISCOVERY_PHASE

Alternatives for Wire.h: [Wire@1.0]

ResolveLibrary(Wire.h)

  -> candidates: [Wire@1.0]

"C:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=153 -DARDUINO=10813 -DARDUINO_TEENSY41 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\cores\\teensy4" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\ADC" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\ILI9341_t3" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\SPI" "-IC:\\Users\\b\\Documents\\Arduino\\libraries\\SdFat-beta-master\\src" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\XPT2046_Touchscreen" "-IC:\\Users\\b\\Documents\\Arduino\\libraries\\MCP4728-master" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\Wire" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\sketch\\H2Regulation.ino.cpp" -o nul -DARDUINO_LIB_DISCOVERY_PHASE

Alternatives for EEPROM.h: [EEPROM@2.0]

ResolveLibrary(EEPROM.h)

  -> candidates: [EEPROM@2.0]

"C:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=153 -DARDUINO=10813 -DARDUINO_TEENSY41 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\cores\\teensy4" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\ADC" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\ILI9341_t3" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\SPI" "-IC:\\Users\\b\\Documents\\Arduino\\libraries\\SdFat-beta-master\\src" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\XPT2046_Touchscreen" "-IC:\\Users\\b\\Documents\\Arduino\\libraries\\MCP4728-master" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\Wire" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\EEPROM" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\sketch\\H2Regulation.ino.cpp" -o nul -DARDUINO_LIB_DISCOVERY_PHASE

Alternatives for SavLayFilter.h: [SavLayFilter-1.0.0@1.0.0]

ResolveLibrary(SavLayFilter.h)

  -> candidates: [SavLayFilter-1.0.0@1.0.0]

"C:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=153 -DARDUINO=10813 -DARDUINO_TEENSY41 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\cores\\teensy4" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\ADC" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\ILI9341_t3" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\SPI" "-IC:\\Users\\b\\Documents\\Arduino\\libraries\\SdFat-beta-master\\src" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\XPT2046_Touchscreen" "-IC:\\Users\\b\\Documents\\Arduino\\libraries\\MCP4728-master" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\Wire" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\EEPROM" "-IC:\\Users\\b\\Documents\\Arduino\\libraries\\SavLayFilter-1.0.0\\src" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\sketch\\H2Regulation.ino.cpp" -o nul -DARDUINO_LIB_DISCOVERY_PHASE

Using cached library dependencies for file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\sketch\font_DroidSansMono.c

Using cached library dependencies for file: C:\zzz\arduino-1.8.13 unmodded\hardware\teensy\avr\libraries\ADC\ADC.cpp

Using cached library dependencies for file: C:\zzz\arduino-1.8.13 unmodded\hardware\teensy\avr\libraries\ADC\ADC_Module.cpp

Using cached library dependencies for file: C:\zzz\arduino-1.8.13 unmodded\hardware\teensy\avr\libraries\ADC\AnalogBufferDMA.cpp

Using cached library dependencies for file: C:\zzz\arduino-1.8.13 unmodded\hardware\teensy\avr\libraries\ILI9341_t3\ILI9341_t3.cpp

Using cached library dependencies for file: C:\zzz\arduino-1.8.13 unmodded\hardware\teensy\avr\libraries\ILI9341_t3\font_Arial.c

Using cached library dependencies for file: C:\zzz\arduino-1.8.13 unmodded\hardware\teensy\avr\libraries\ILI9341_t3\font_ArialBold.c

Using cached library dependencies for file: C:\zzz\arduino-1.8.13 unmodded\hardware\teensy\avr\libraries\ILI9341_t3\glcdfont.c

Using cached library dependencies for file: C:\zzz\arduino-1.8.13 unmodded\hardware\teensy\avr\libraries\SPI\SPI.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\ExFatLib\ExFatDbg.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\ExFatLib\ExFatFile.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\ExFatLib\ExFatFilePrint.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\ExFatLib\ExFatFileWrite.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\ExFatLib\ExFatFormatter.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\ExFatLib\ExFatPartition.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\ExFatLib\ExFatVolume.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\ExFatLib\upcase.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\FatLib\FatDbg.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\FatLib\FatFile.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\FatLib\FatFileLFN.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\FatLib\FatFilePrint.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\FatLib\FatFileSFN.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\FatLib\FatFormatter.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\FatLib\FatPartition.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\FatLib\FatVolume.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\FreeStack.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\FsLib\FsFile.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\FsLib\FsNew.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\FsLib\FsVolume.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\MinimumSerial.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\SdCard\SdCardInfo.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\SdCard\SdSpiCard.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\SdCard\SdioTeensy.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\SpiDriver\SdSpiArtemis.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\SpiDriver\SdSpiChipSelect.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\SpiDriver\SdSpiDue.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\SpiDriver\SdSpiESP.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\SpiDriver\SdSpiParticle.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\SpiDriver\SdSpiSTM32.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\SpiDriver\SdSpiTeensy3.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\common\FmtNumber.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\common\FsDateTime.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\common\FsStructs.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\common\PrintBasic.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\common\SysCallBareUno.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\iostream\StdioStream.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\iostream\StreamBaseClass.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\iostream\istream.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master\src\iostream\ostream.cpp

Using cached library dependencies for file: C:\zzz\arduino-1.8.13 unmodded\hardware\teensy\avr\libraries\XPT2046_Touchscreen\XPT2046_Touchscreen.cpp

Using cached library dependencies for file: C:\zzz\arduino-1.8.13 unmodded\hardware\teensy\avr\libraries\Wire\Wire.cpp

Using cached library dependencies for file: C:\zzz\arduino-1.8.13 unmodded\hardware\teensy\avr\libraries\Wire\WireIMXRT.cpp

Using cached library dependencies for file: C:\zzz\arduino-1.8.13 unmodded\hardware\teensy\avr\libraries\Wire\WireKinetis.cpp

Using cached library dependencies for file: C:\zzz\arduino-1.8.13 unmodded\hardware\teensy\avr\libraries\Wire\utility\twi.c

Using cached library dependencies for file: C:\zzz\arduino-1.8.13 unmodded\hardware\teensy\avr\libraries\EEPROM\EEPROM.cpp

Using cached library dependencies for file: C:\Users\b\Documents\Arduino\libraries\SavLayFilter-1.0.0\src\SavLayFilter.cpp

Generating function prototypes...

"C:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=153 -DARDUINO=10813 -DARDUINO_TEENSY41 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\cores\\teensy4" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\ADC" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\ILI9341_t3" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\SPI" "-IC:\\Users\\b\\Documents\\Arduino\\libraries\\SdFat-beta-master\\src" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\XPT2046_Touchscreen" "-IC:\\Users\\b\\Documents\\Arduino\\libraries\\MCP4728-master" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\Wire" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\EEPROM" "-IC:\\Users\\b\\Documents\\Arduino\\libraries\\SavLayFilter-1.0.0\\src" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\sketch\\H2Regulation.ino.cpp" -o "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\preproc\\ctags_target_for_gcc_minus_e.cpp" -DARDUINO_LIB_DISCOVERY_PHASE

"C:\\zzz\\arduino-1.8.13 unmodded\\tools-builder\\ctags\\5.8-arduino11/ctags" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\preproc\\ctags_target_for_gcc_minus_e.cpp"

Compiling sketch...

"C:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy/../tools/precompile_helper" "C:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr/cores/teensy4" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557" "C:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -x c++-header -O2 -g -Wall -ffunction-sections -fdata-sections -nostdlib -MMD -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=153 -DARDUINO=10813 -DARDUINO_TEENSY41 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr/cores/teensy4" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557/pch/Arduino.h" -o "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557/pch/Arduino.h.gch"

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\pch\Arduino.h.gch

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\sketch\font_DroidSansMono.c.o

"C:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -c -O2 -g -Wall -ffunction-sections -fdata-sections -nostdlib -MMD -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=153 -DARDUINO=10813 -DARDUINO_TEENSY41 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557/pch" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\cores\\teensy4" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\ADC" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\ILI9341_t3" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\SPI" "-IC:\\Users\\b\\Documents\\Arduino\\libraries\\SdFat-beta-master\\src" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\XPT2046_Touchscreen" "-IC:\\Users\\b\\Documents\\Arduino\\libraries\\MCP4728-master" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\Wire" "-IC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\libraries\\EEPROM" "-IC:\\Users\\b\\Documents\\Arduino\\libraries\\SavLayFilter-1.0.0\\src" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\sketch\\H2Regulation.ino.cpp" -o "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\sketch\\H2Regulation.ino.cpp.o"

H2Regulation:462: warning: "/*" within comment 

     /*if (filterOutputReady == true){

     ^

H2Regulation:1557: warning: "/*" within comment 

   /*void dumpDMA_structures(DMABaseClass *dmabc){

   ^

H2Regulation: In function 'void processADC()':

H2Regulation:402: warning: variable 'timerForGraphs' set but not used 

   static unsigned long timerForGraphs;  // always reseted after one buffer pair is filled, so no problems can accumulate

                        ^

H2Regulation: In function 'void ProcessAnalogData(AnalogBufferDMA*, int8_t)':

H2Regulation:436: warning: unused variable 'sum_delta_sq' 

   float sum_delta_sq = 0.0;

         ^

H2Regulation: In function 'float calculateSlugspeed(float, uint8_t)':

H2Regulation:712: warning: statement has no effect 

         speedCalcFrame [0] == false;

                            ^

H2Regulation:593: warning: unused variable 'calculateSlugspeedCounter' 

   static uint8_t calculateSlugspeedCounter [2];

                  ^

H2Regulation:606: warning: variable 'lastSpeedFrame' set but not used 

   static uint32_t lastSpeedFrame [2] = {0,0};

                   ^

H2Regulation:624: warning: unused variable 'phasePercentageFrameReady' 

   static bool phasePercentageFrameReady = false;

               ^

H2Regulation:625: warning: variable 'phasePercentageFrame' set but not used 

   static uint32_t phasePercentageFrame;

                   ^

H2Regulation: In function 'void calculateSlugSpeedSavGol()':

H2Regulation:810: warning: comparison between signed and unsigned integer expressions 

   for (int i = 0; i<buffer_size ;i++){

                    ^

H2Regulation:847: warning: unused variable 'tempMax' 

           static double tempMax [2] = {0,0};

                         ^

H2Regulation:783: warning: unused variable 'startSavGolTimer' 

   static uint32_t startSavGolTimer = millis();

                   ^

H2Regulation: In function 'float calculateCenterOfGravity(float*, uint32_t)':

H2Regulation:916: warning: comparison between signed and unsigned integer expressions 

   for (int j = 0; j < numberOfValues; j++){

                     ^

H2Regulation: In function 'void graphPrintOnScreen()':

H2Regulation:965: warning: unused variable 'RefreshRate' 

     const uint8_t RefreshRate = 2; //hz

                   ^

H2Regulation:966: warning: variable 'startOfTimer' set but not used 

     static unsigned long startOfTimer = millis();

                          ^

H2Regulation:995: warning: comparison between signed and unsigned integer expressions 

     for (int i = 0; i<buffer_size ;i++){

                      ^

H2Regulation:924: warning: variable 'speedMillis' set but not used 

   static uint16_t speedMillis;

                   ^

H2Regulation:930: warning: label 'slugspeed' defined but not used 

     slugspeed:

     ^

H2Regulation: In function 'void printGraphToSerial()':

H2Regulation:1137: warning: comparison between signed and unsigned integer expressions 

     for (int i = 0; i<buffer_size ;i++){

                      ^

H2Regulation:1141: warning: unused variable 'filteredADC0SavLayForPrinting' 

         double filteredADC0SavLayForPrinting = filterADC0ForPrinting.Compute()*20;

                ^

H2Regulation:1142: warning: unused variable 'filteredADC1SavLayForPrinting' 

         double filteredADC1SavLayForPrinting = filterADC1ForPrinting.Compute()*20;

                ^

H2Regulation: In function 'void calibrateRegressionCurve()':

H2Regulation:1166: warning: statement has no effect 

   curveCoeffPairs [0] [0];

                         ^

H2Regulation:1167: warning: statement has no effect 

   curveCoeffPairs [1] [0];

                         ^

H2Regulation:1184: warning: comparison between signed and unsigned integer expressions 

     else if (startRecordingSpeed == true && millis()-timerStart>= int(float(125/i))){

                                                                ^

H2Regulation:1215: warning: comparison between signed and unsigned integer expressions 

       for (int j = 0; j < sizeof(regressionCurveCoeffs)/sizeof(double); j++){

                         ^

H2Regulation:1213: warning: unused variable 'ret' 

       int ret = fitCurve(regressionCurveOrder, sizeof(curveCoeffPairs[0])/sizeof(double), curveCoeffPairs[0], curveCoeffPairs[1], sizeof(regressionCurveCoeffs)/sizeof(double), regressionCurveCoeffs);

           ^

H2Regulation:1168: warning: unused variable 'singleValueArray' 

   double singleValueArray [10];

          ^

H2Regulation: In function 'void regulateSlugspeed()':

H2Regulation:1252: warning: statement has no effect 

     desiredSlugspeedChanged == true;

                             ^

H2Regulation: In function 'double regulatePhase()':

H2Regulation:1298: warning: unused variable 'kd_ph' 

   const double kd_ph = 0;

                ^

H2Regulation:1301: warning: variable 'last_e' set but not used 

   static double last_e = 0;

                 ^

H2Regulation: In function 'void modifySlugspeed()':

H2Regulation:1332: warning: comparison between signed and unsigned integer expressions 

   else if (millis() - startModSlugTimer >= int(15000/slugSpeed)){

                                         ^

H2Regulation:1320: warning: variable 'doRegulation' set but not used 

   static bool doRegulation = false;

               ^

H2Regulation: In function 'void writeToSD()':

H2Regulation:1488: warning: comparison between signed and unsigned integer expressions 

     for (int i = 0; i < buffer_size; i=i+2){

                       ^

H2Regulation:1490: warning: unused variable 'msBetweenValues' 

       static const double msBetweenValues = 1000/double(ADC_frequency);

                           ^

H2Regulation: In function 'float calculateSlugspeed(float, uint8_t)':

H2Regulation:766: warning: control reaches end of non-void function 

 }

 ^

Compiling libraries...

Compiling library "ADC"

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\ADC\AnalogBufferDMA.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\ADC\ADC_Module.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\ADC\ADC.cpp.o

Compiling library "ILI9341_t3"

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\ILI9341_t3\font_Arial.c.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\ILI9341_t3\font_ArialBold.c.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\ILI9341_t3\glcdfont.c.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\ILI9341_t3\ILI9341_t3.cpp.o

Compiling library "SPI"

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SPI\SPI.cpp.o

Compiling library "SdFat-beta-master"

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\FreeStack.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\MinimumSerial.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\ExFatLib\ExFatDbg.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\ExFatLib\ExFatFormatter.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\ExFatLib\ExFatFile.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\ExFatLib\ExFatPartition.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\ExFatLib\ExFatFilePrint.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\ExFatLib\ExFatVolume.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\ExFatLib\upcase.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\ExFatLib\ExFatFileWrite.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\FatLib\FatFileLFN.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\FatLib\FatFileSFN.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\FatLib\FatFormatter.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\FatLib\FatDbg.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\FatLib\FatVolume.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\FatLib\FatFile.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\FatLib\FatPartition.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\FatLib\FatFilePrint.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\FsLib\FsNew.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\FsLib\FsFile.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\FsLib\FsVolume.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\SdCard\SdCardInfo.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\SdCard\SdioTeensy.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\SdCard\SdSpiCard.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\SpiDriver\SdSpiArtemis.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\SpiDriver\SdSpiTeensy3.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\SpiDriver\SdSpiDue.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\SpiDriver\SdSpiParticle.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\SpiDriver\SdSpiESP.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\SpiDriver\SdSpiChipSelect.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\SpiDriver\SdSpiSTM32.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\common\FmtNumber.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\common\FsStructs.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\common\PrintBasic.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\common\SysCallBareUno.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\common\FsDateTime.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\iostream\istream.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\iostream\StdioStream.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\iostream\ostream.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SdFat-beta-master\iostream\StreamBaseClass.cpp.o

Compiling library "XPT2046_Touchscreen"

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\XPT2046_Touchscreen\XPT2046_Touchscreen.cpp.o

Compiling library "MCP4728-master"

Compiling library "Wire"

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\Wire\Wire.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\Wire\WireKinetis.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\Wire\WireIMXRT.cpp.o

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\Wire\utility\twi.c.o

Compiling library "EEPROM"

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\EEPROM\EEPROM.cpp.o

Compiling library "SavLayFilter-1.0.0"

Using previously compiled file: C:\Users\b\AppData\Local\Temp\arduino_build_696557\libraries\SavLayFilter-1.0.0\SavLayFilter.cpp.o

Compiling core...

Using precompiled core: C:\Users\b\AppData\Local\Temp\arduino_cache_303420\core\core_5922bb2e922fb56a37e6bc86602f7944.a

Linking everything together...

"C:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-gcc" -O2 -Wl,--gc-sections,--relax "-TC:\\zzz\\arduino-1.8.13 unmodded\\hardware\\teensy\\avr\\cores\\teensy4/imxrt1062_t41.ld" -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -o "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557/H2Regulation.ino.elf" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\sketch\\font_DroidSansMono.c.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\sketch\\H2Regulation.ino.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\ADC\\ADC.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\ADC\\ADC_Module.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\ADC\\AnalogBufferDMA.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\ILI9341_t3\\font_Arial.c.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\ILI9341_t3\\font_ArialBold.c.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\ILI9341_t3\\glcdfont.c.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\ILI9341_t3\\ILI9341_t3.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SPI\\SPI.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\FreeStack.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\MinimumSerial.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\ExFatLib\\ExFatDbg.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\ExFatLib\\ExFatFile.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\ExFatLib\\ExFatFilePrint.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\ExFatLib\\ExFatFileWrite.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\ExFatLib\\ExFatFormatter.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\ExFatLib\\ExFatPartition.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\ExFatLib\\ExFatVolume.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\ExFatLib\\upcase.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\FatLib\\FatDbg.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\FatLib\\FatFile.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\FatLib\\FatFileLFN.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\FatLib\\FatFilePrint.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\FatLib\\FatFileSFN.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\FatLib\\FatFormatter.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\FatLib\\FatPartition.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\FatLib\\FatVolume.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\FsLib\\FsFile.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\FsLib\\FsNew.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\FsLib\\FsVolume.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\SdCard\\SdCardInfo.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\SdCard\\SdSpiCard.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\SdCard\\SdioTeensy.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\SpiDriver\\SdSpiArtemis.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\SpiDriver\\SdSpiChipSelect.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\SpiDriver\\SdSpiDue.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\SpiDriver\\SdSpiESP.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\SpiDriver\\SdSpiParticle.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\SpiDriver\\SdSpiSTM32.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\SpiDriver\\SdSpiTeensy3.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\common\\FmtNumber.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\common\\FsDateTime.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\common\\FsStructs.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\common\\PrintBasic.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\common\\SysCallBareUno.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\iostream\\StdioStream.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\iostream\\StreamBaseClass.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\iostream\\istream.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SdFat-beta-master\\iostream\\ostream.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\XPT2046_Touchscreen\\XPT2046_Touchscreen.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\Wire\\Wire.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\Wire\\WireIMXRT.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\Wire\\WireKinetis.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\Wire\\utility\\twi.c.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\EEPROM\\EEPROM.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557\\libraries\\SavLayFilter-1.0.0\\SavLayFilter.cpp.o" "C:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557/..\\arduino_cache_303420\\core\\core_5922bb2e922fb56a37e6bc86602f7944.a" "-LC:\\Users\\b\\AppData\\Local\\Temp\\arduino_build_696557" -larm_cortexM7lfsp_math -lm -lstdc++

C:\Users\b\AppData\Local\Temp\arduino_build_696557\sketch\H2Regulation.ino.cpp.o: In function `initializeADC_and_Buffer()':

C:\Users\b\Dropbox\Arduino\a\H2Regulation/H2Regulation.ino:378: undefined reference to `AnalogBufferDMA::init(ADC*, signed char)'

C:\Users\b\Dropbox\Arduino\a\H2Regulation/H2Regulation.ino:381: undefined reference to `AnalogBufferDMA::init(ADC*, signed char)'

collect2.exe: error: ld returned 1 exit status

Using library ADC at version 8.0 in folder: C:\zzz\arduino-1.8.13 unmodded\hardware\teensy\avr\libraries\ADC 

Using library ILI9341_t3 at version 1.0 in folder: C:\zzz\arduino-1.8.13 unmodded\hardware\teensy\avr\libraries\ILI9341_t3 

Using library SPI at version 1.0 in folder: C:\zzz\arduino-1.8.13 unmodded\hardware\teensy\avr\libraries\SPI 

Using library SdFat-beta-master at version 2.0.0-beta.8 in folder: C:\Users\b\Documents\Arduino\libraries\SdFat-beta-master 

Using library XPT2046_Touchscreen at version 1.3 in folder: C:\zzz\arduino-1.8.13 unmodded\hardware\teensy\avr\libraries\XPT2046_Touchscreen 

Using library MCP4728-master at version 0.1.0 in folder: C:\Users\b\Documents\Arduino\libraries\MCP4728-master 

Using library Wire at version 1.0 in folder: C:\zzz\arduino-1.8.13 unmodded\hardware\teensy\avr\libraries\Wire 

Using library EEPROM at version 2.0 in folder: C:\zzz\arduino-1.8.13 unmodded\hardware\teensy\avr\libraries\EEPROM 

Using library SavLayFilter-1.0.0 at version 1.0.0 in folder: C:\Users\b\Documents\Arduino\libraries\SavLayFilter-1.0.0 

Error compiling for board Teensy 4.1.

My sketch (sorry, it's not very structured, i just wrote it down in 2 weeks):

Code:
// name definition for outputBuffer array [ADC_num] [raw data/ moving average/ 1st derivetive/ 2nd derivative] [buffered values]
#define raw 0
#define movAvg 1
#define derive1st 2
#define derive2nd 3

// H2-switch (because DAC is not turning off completly, when set to 0
uint8_t H2Switch = 22; //hydrogen switch
// rotary encoder button
uint8_t rotEncBtn = 21;

#include <ADC.h>                  // extended analog read functions
#include <DMAChannel.h>           // saving CPU resources while reading ADC values
#include <AnalogBufferDMA.h>      // saving CPU resources while reading ADC values
#include "font_DroidSansMono.h"
#include <SPI.h>                  // communication with display and touchscreen
#include <SdFat.h>                // using SdFat beta for exFat support (sideload: https://github.com/greiman/SdFat-beta)
#include <ILI9341_t3.h>           // Display library
#include <XPT2046_Touchscreen.h>  // Touchscreen library
#include <MCP4728.h>               // hideakitai mcp4728 DAC library (sideload: https://github.com/hideakitai/MCP4728)
#include <Wire.h>                 // i2c
#include <WireIMXRT.h>
#include <WireKinetis.h>
#include <EEPROM.h>               // for saving settings when powered down
#include <SavLayFilter.h>         // Savitzky-Golay Filter for smoothing the noise (sideload: https://github.com/jmderomedi/SavitzkyGolayFilter)
//#include "arduino-pid-autotuner-master\pidautotuner.h"    //
#include "arduinoCurveFitting-master\src\curveFitting.h"  // regression for simple slugspeed prediction (sideload: https://github.com/Rotario/arduinoCurveFitting)

// SD
SdExFat SD;                       // pls use ExFat formatted sd cards (standard for 64GB or bigger cards)
#define SD_CONFIG SdioConfig(FIFO_SDIO) // using SdioConfig(FIFO_SDIO) (much faster than spi)
ExFile myFile;


// EEPROM
/*use EEPROM.put(address,data) and EEROM.get(address,data)! (adress points to 1 byte, if you need more than one, the ones after are used)
  eeAddress 0:MinXTouch);
  eeAddress 2:MinYTouch);
  eeAddress 4:MaxXTouch);
  eeAddress 6:MaxYTouch);
  eeAddress 8: regressionCurveCoeffs[0]
  eeAddress 16: regressionCurveCoeffs[1]
  eeAddress 24: regressionCurveCoeffs[2]
*/


// ILI9341 Display
#define TFT_DC  9
#define TFT_CS 10
ILI9341_t3 tft = ILI9341_t3(TFT_CS, TFT_DC);
const uint8_t displayRotation = 3; // ϵ [0,3]. 1 and 3 is widescreen //code not written for upright
const uint16_t xDispResolution = 320, yDispResolution = 240;



// Touchscreen
#define Touch_CS_PIN  8
// MOSI=11, MISO=12, SCK=13
#define Touch_IRQ_PIN  2
XPT2046_Touchscreen touchscreen(Touch_CS_PIN, Touch_IRQ_PIN);  // Param 2 - Touch IRQ Pin - interrupt enabled polling
TS_Point TouchDataRaw; //Touchscreenobject: p.x,p.y give location, p.z pressure (0-4095)
uint16_t MinXTouch, MinYTouch, MaxXTouch, MaxYTouch = 0;




// DAC: MCP4728
MCP4728 dac;
const uint8_t MCP4728_LDAC_PIN = 6; //set high for write to buffer, set low after for update DAC on all channels at once
// Pin 18 and 19 (i2c0) used for i2c (SDA, SCL connection)


// Savitzky-Golay Filter
const int windowSize = 25; // window size for Savitzky-Golay qubic filter (use: 5,7,...,23,25)
double ADC0SavLayValue, ADC1SavLayValue;
SavLayFilter filterADC0 (&ADC0SavLayValue, 1, windowSize);
SavLayFilter filterADC1 (&ADC1SavLayValue, 1, windowSize);

double ADC0SavLayForPrinting, ADC1SavLayForPrinting;
SavLayFilter filterADC0ForPrinting (&ADC0SavLayForPrinting, 1, windowSize);
SavLayFilter filterADC1ForPrinting (&ADC1SavLayForPrinting, 1, windowSize);

// moving average filter
uint8_t movingAverageWindowSize = 128; // actual window size to calculate the moving average, must be smaller than: maxMovingAverageWindowSize
const uint8_t maxMovingAverageWindowSize = 128; //the maximum number of values used to calculate the moxing average

// internal ADC
#ifdef KINETISL
#error "Sorry: This example will not run on Teensy LC"
#endif


//KINETISK = teensy 3.x
#ifdef KINETISK
const int readPin_adc_0 = A9;
const int readPin_adc_1 = A3;
#else
const int readPin_adc_0 = A9;
const int readPin_adc_1 = A3;
#endif

ADC *adc = new ADC(); // adc object

const int ADC_frequency = 19200;//49920/4;  //reads per second. Dividable by 320 (x axis display pixel) and up to 2^8=256 for int math without rest.
const uint32_t initial_average_value = 2048;

extern void dumpDMA_structures(DMABaseClass *dmabc);
unsigned long initMicrosADC1; // to check how long it took to initialize the second ADC in µs


// Going to try two buffers here  using 2 dmaSettings and a DMAChannel
const uint32_t buffer_size = ADC_frequency/20; // buffer size in number of values
/* DMAMEM -> lower half of RAM (KINETISK) or separate RAM (teensy 4.0)
   static -> allocated at the beginning-, deallocated at the end of the program (https://en.cppreference.com/w/cpp/language/storage_duration)
   __attribute__ ((aligned(32))) -> storing a 32bit value consecutively; 4 bytes together
*/
DMAMEM static volatile uint16_t __attribute__((aligned(32))) dma_adc_buff1[buffer_size];
DMAMEM static volatile uint16_t __attribute__((aligned(32))) dma_adc_buff2[buffer_size];
AnalogBufferDMA abdma1(dma_adc_buff1, buffer_size, dma_adc_buff2, buffer_size);

#ifdef ADC_DUAL_ADCS
DMAMEM static volatile uint16_t __attribute__((aligned(32))) dma_adc_buff2_1[buffer_size];
DMAMEM static volatile uint16_t __attribute__((aligned(32))) dma_adc_buff2_2[buffer_size];
AnalogBufferDMA abdma2(dma_adc_buff2_1, buffer_size, dma_adc_buff2_2, buffer_size);
#endif

//--variables--
double slugSpeed = 0;
double savGolPhasePercentage = 50;
volatile double desiredSlugspeed = 0;
double phasePercentage = 50;
volatile double desiredPhasePercentage = 50;
bool doPhaseRegulation = true;

const double distanceSensors = 6; //in mm
const uint8_t characterHeight = 14; // check font in initializeTFT if not right
const uint8_t characterWidth  = characterHeight*3/4;

int16_t graphValuesADC [2][xDispResolution]; //row0:ADC0, row1:ADC1
uint16_t graphHeight = yDispResolution - 4 * characterHeight;
uint32_t graphTimeFrameSecs = 5; // how many millisecs shown on screen at the same time
uint32_t graphSpeedRefreshMillis = 1000; // how many millis between each refresh of desired slugspeed and slugspeed on screen
bool graphPrintDataReady = false;
bool doDisplayGraphPrinting = true;
bool speedPrinting = true;
bool newDesiredSlugspeedValueToPrintOnScreen = false;   //to know, when a new value is available to print on screen
bool newDireredSlugspeedToRegulation = true;            //to know, when a new dac control is needed, before regulation
bool newSlugspeedValueReadyForPrinting = false;         //to know, when a new slug speed and phase percentage value is available to print on screen

// global regression curve calculation variables:
const int regressionCurveOrder = 2;
double regressionCurveCoeffs[regressionCurveOrder+1];
const double upperLimitCalibrationCurve = 0.4;

// regulation variables:
double kp = 0.0042525;    //values for PI regulator
double ki = 0.002751618;  //values for PI regulator
double kd;
const uint16_t NumberOfValuesForIntegralSum = 3;
bool newSlugspeedValueReadyForRegulation = false;
bool startRegulateSlugspeed = true;
bool doPIDRegulation = true;
bool speedRegulationDone = false;
float y; //the calculated input value for both DACs, might be modified in regulatePhase()

bool writeRawDataToSD = false;

bool newSlugspeedValueReadyForSD;

bool filterOutputReady = false;

bool newGraphBufferFilled = false;              // turns true, when adc0 and adc1 values were filtered and copied
double outputBuffer [2] [4] [buffer_size];      // buffer to store the filtered values for graphs, [ADC_NUM]: 0,1 ; [Value]: 0= raw, 1=moving average, 2= 1st derivate, 3= 2nd derivate. 

// graph to Serial.print variables
uint16_t graphValuesPerSecond = 320;             // how many values should be printed to screen (if too many, serial plotter is too fast or pc cannot follow)
uint32_t graphFrameInterval = ADC_frequency/graphValuesPerSecond;

uint8_t currentCharNumber = 0;  // didn't work as a static local variable, don't know why

const uint32_t bufferTimeFrameMillis = buffer_size * 1000 / ADC_frequency; //in milliseconds
//uint32_t bufferedValuesPerDisplayPixel = buffer_size * graphTimeFrameMillis / 1000 / xDispResolution * 1000 / bufferTimeFrameMillis;


//all the Dos:
volatile bool doWriteToSD = true;
bool doGraphPrintingToSerial = false;
bool displayPrinting = false; // should graph be printed on TFT screen

//NEW VARIABLES FOR ELECTROLYSIS CELL
double amperagePercentage = 0;


//--functions--
void initalizeSD() {
  tft.print("Initializing SD card...");
  Serial.println("Initializing SD card...");
  delay(500);

  if (!SD.begin(SD_CONFIG)) {
    tft.println("failed!");
    Serial.println("failed!");
    tft.print("start reboot");
    Serial.println("start reboot");
    //_reboot_Teensyduino_(); //works on Teensy 3.6, not 4 r 4.1
    while (true) {}
    return;
  }
  myFile = SD.open(findNextFreeFilenameOnSD(), FILE_WRITE);
  if (!myFile) {
    tft.println("error opening file");
    Serial.println("error opening file");
    while (true) {}
  }
  else {
    tft.println("done.");
    Serial.println("done.");
  }
}
char * findNextFreeFilenameOnSD() { //format is "number".csv, counting up from 0.csv
  static char filename[15] = "0.csv";
  static uint32_t filenameCounter = 0;
  while (SD.exists(filename)) {
    if (filenameCounter == 0xffffffff) {
      tft.println("no free filename found");
      while (true) {}
    }
    filenameCounter++;
    itoa (filenameCounter, filename, 10);
    strcat (filename, ".csv"); // strcar adds the null character at the end.
  }
  return filename;
}
bool loadTouchBordersFromEEPROM() {
  uint16_t tempBorders [4];
  for (int i = 0; i < 7; i = i + 2) {
    EEPROM.get( i, tempBorders[i / 2]); //write preivious calibration data from EEPROM to array: tempBoarders
    Serial.println(tempBorders[i / 2]);
  }

  //check if numbers are plausible, then write to global variable:
  if (tempBorders[0] < 500 && tempBorders[1] && tempBorders[2] > 3545 && tempBorders[3] > 3545) {
    MinXTouch = tempBorders[0];
    MinYTouch = tempBorders[1];
    MaxXTouch = tempBorders[2];
    MaxYTouch = tempBorders[3];
    tft.println("Touchscreen calibration load from EEPROM");
#ifdef DEBUG
    tft.print("Min Border X = ");
    tft.println(MinXTouch);
    tft.print("Min Border Y = ");
    tft.println(MinYTouch);
    tft.print("Max Border X = ");
    tft.println(MaxXTouch);
    tft.print("Max Border Y = ");
    tft.println(MaxYTouch);
#endif
    return true;
  }
  else {
    return false;
  }
}
void initializeTFT() {
  tft.begin();
  tft.setRotation(displayRotation);
  tft.fillScreen(ILI9341_BLACK);
  tft.setTextColor(ILI9341_YELLOW);
  tft.setFont(DroidSansMono_10);
  //tft.setTextSize(2);
  tft.println("TFT initalized");
}
void emptyGraphs() {
  memset(graphValuesADC, 0, sizeof(graphValuesADC));
}
void calibrateTouchscreen () {
  delay (2000);
  tft.fillScreen(ILI9341_BLACK);
  tft.setCursor(0, 0);
  while (touchscreen.touched()) {}
  tft.println("Touchscreen Calibration:");
  tft.println("Touch the yellow rect-");
  tft.println("angles to calibrate");
  tft.println("");
  tft.println("Touch to begin");
  while (!touchscreen.touched()) {}
  tft.fillScreen(ILI9341_BLACK);
  tft.fillRect(0, 0, 10, 10, ILI9341_YELLOW);
  while (touchscreen.touched()) {}
  while (!touchscreen.touched()) {}
  updateTouchPoints();
  MinXTouch = TouchDataRaw.x;
  MinYTouch = TouchDataRaw.y;
  while (touchscreen.touched()) {}
  if (MinXTouch > 500 || MinYTouch > 500) {
    calibrateTouchscreen();
  }
  tft.fillScreen(ILI9341_BLACK);
  tft.fillRect(310, 230, 10, 10, ILI9341_YELLOW);
  while (!touchscreen.touched()) {}
  updateTouchPoints();
  MaxXTouch = TouchDataRaw.x;
  MaxYTouch = TouchDataRaw.y;
  while (touchscreen.touched()) {}
  if (MaxXTouch < 3545 || MaxYTouch < 3545) {
    calibrateTouchscreen();
  }
  tft.fillScreen(ILI9341_BLACK);
  tft.setCursor(0, 0);
  tft.print("X Min ist: ");
  tft.println(MinXTouch);
  tft.print("Y Min ist: ");
  tft.println(MinYTouch);
  tft.print("X Max ist: ");
  tft.println(MaxXTouch);
  tft.print("Y Max ist: ");
  tft.println(MaxYTouch);
  EEPROM.put(0, MinXTouch);
  EEPROM.put(2, MinYTouch);
  EEPROM.put(4, MaxXTouch);
  EEPROM.put(6, MaxYTouch);
  tft.println("Touch to continue");
  while (touchscreen.touched()) {}
  tft.setCursor(0, 0);
  tft.println("Touchscreen calibrated and data saved to EEPROM");
}
void convertTouchInputToRealValues () {

}
void initalizeTouchscreen() {
  tft.print("Initializing touchscreen...");
  touchscreen.begin();
  touchscreen.setRotation(displayRotation);
  tft.println("done");
}
void updateTouchPoints() {
  if (touchscreen.tirqTouched()) {
    if (touchscreen.touched()) {
      TouchDataRaw = touchscreen.getPoint();
#ifdef DEBUG
      Serial.print("Pressure = ");
      Serial.print(TouchDataRaw.z);
      Serial.print(", x = ");
      Serial.print(TouchDataRaw.x);
      Serial.print(", y = ");
      Serial.print(TouchDataRaw.y);
      Serial.println();
#endif
    }
  }
}
void initializeADC_and_Buffer() {
  //tft.print("Initializing ADC and Buffer...");
  pinMode(readPin_adc_0, INPUT); // Not sure this does anything for us
#ifdef ADC_DUAL_ADCS
  pinMode(readPin_adc_1, INPUT);
#endif

  Serial.println("Setup both ADCs");
  // Setup both ADCs
  adc->adc0->setAveraging(4); // set number of averages
  adc->adc0->setResolution(12); // set bits of resolution
  adc->adc0->setConversionSpeed(ADC_CONVERSION_SPEED::MED_SPEED);  // LOW: more time to read the voltage
  adc->adc0->setSamplingSpeed(ADC_SAMPLING_SPEED::LOW_SPEED); // LOW: more time to load the capacitor
#ifdef ADC_DUAL_ADCS
  adc->adc1->setAveraging(4); // set number of averages
  adc->adc1->setResolution(12); // set bits of resolution
  adc->adc1->setConversionSpeed(ADC_CONVERSION_SPEED::MED_SPEED);  // LOW: more time to read the voltage
  adc->adc1->setSamplingSpeed(ADC_SAMPLING_SPEED::LOW_SPEED); // LOW: more time to load the capacitor
#endif

  // enable DMA and interrupts
  //Serial.println("before enableDMA"); Serial.flush();


  // setup a DMA Channel.
  // Now lets see the different things that RingbufferDMA setup for us before
  abdma1.init(adc, ADC_0/*, DMAMUX_SOURCE_ADC_ETC*/);
  abdma1.userData(initial_average_value); // save away initial starting average
#ifdef ADC_DUAL_ADCS
  abdma2.init(adc, ADC_1/*, DMAMUX_SOURCE_ADC_ETC*/);
  abdma2.userData(initial_average_value); // save away initial starting average
#endif
  delay (3000);

  // Start the dma operation..
  adc->adc0->startSingleRead(readPin_adc_0); // call this to setup everything before the Timer starts, differential is also possible
  adc->adc0->startTimer(ADC_frequency); //frequency in Hz

  initMicrosADC1 = micros(); //start timer to see adc1 initiation time
  // Start the dma operation..
#ifdef ADC_DUAL_ADCS
  adc->adc1->startSingleRead(readPin_adc_1); // call this to setup everything before the Timer starts, differential is also possible
  adc->adc1->startTimer(ADC_frequency); //frequency in Hz
#endif
  initMicrosADC1 = micros() - initMicrosADC1; // end initiation timer

  //print_ADC_debug_information();
  //tft.println("done");
}
void processADC() {
  static unsigned long timerForGraphs;  // always reseted after one buffer pair is filled, so no problems can accumulate
  static uint8_t runThroughCounter = 0;
  if ( abdma1.interrupted() && (abdma2.interrupted())) {
    //int mics = micros();
    if ( abdma1.interrupted()) {
      ProcessAnalogData(&abdma1, 0);
    }
    if ( abdma2.interrupted()) {
      ProcessAnalogData(&abdma2, 1);
    }
    //Serial.println();
    //Serial.print("Time to process ADC data: ");
    //Serial.print(micros() - mics);
    //Serial.println(" µs");
    //Serial.println();
    timerForGraphs = micros();
    newGraphBufferFilled = true;
    if (graphPrintDataReady == false && runThroughCounter != 2){
      runThroughCounter++;
      if (runThroughCounter == 2) {
        graphPrintDataReady = true; //set flag for data being ready to print after 2 runthroughs
      }
    }
  }
}
void ProcessAnalogData(AnalogBufferDMA *pabdma, int8_t adc_num) {
  //array for saving current pixel data on screen
  static uint16_t xPixelCounter [2] = {0, 0}; //counts up, if new data for the next pixel of the graph was saved

  uint32_t average_value = pabdma->userData();

  volatile uint16_t *pbuffer = pabdma->bufferLastISRFilled();
  volatile uint16_t *end_pbuffer = pbuffer + pabdma->bufferCountLastISRFilled();

  float sum_delta_sq = 0.0;
  if ((uint32_t)pbuffer >= 0x20200000u)  arm_dcache_delete((void*)pbuffer, sizeof(dma_adc_buff1));

  uint16_t counter = 0;
  static bool bufferHalfFilled = false;
  
  if (xPixelCounter[adc_num] >= xDispResolution) {
    xPixelCounter[adc_num] = 0;
  }

  while (pbuffer < end_pbuffer) {

    //write raw data to buffer
    
    
    // write raw data to CSV on SD card:
    /*if(writeRawDataToSD == true){
      if (counter == 0) {
        myFile.print("ADC");
        myFile.print(adc_num);
        myFile.print(";");
      }
      myFile.print(*pbuffer);
      myFile.print(";");
    }

    /*if (filterOutputReady == true){
      calculateSlugspeed(filterOutput, adc_num);
    }*/
    //filter the buffered values:
    float filterOutput = movingAverage(false, *pbuffer, adc_num);
    
    //outputBuffer for storing all values:
    outputBuffer [adc_num] [raw] [counter] = *pbuffer;
    outputBuffer [adc_num] [movAvg] [counter] = filterOutput;
    // outputBuffer [adc_num] [derive1st] [counter] = 
    // outputBuffer [adc_num] [derive2nd] [counter] = 
    /*if (adc_num == 0){
      ADC0FilterInput = float(*pbuffer);
      filterOutput = filterADC0.Compute();
      }
      if (adc_num == 1){
      ADC1FilterInput = float(*pbuffer);
      filterOutput = filterADC1.Compute();
      }*/

//    // write data to graphValuesADC1 and 2 for printing on screen
//    if (displayPrinting && counter % bufferedValuesPerDisplayPixel == 0) { // if graph is printed and we hit the next pixel
//      graphValuesADC[adc_num][xPixelCounter[adc_num]] = (*pbuffer * (graphHeight - 1)) / 4095;
//      /*if (adc_num == 1) {
//        Serial.print("ADC");
//        Serial.print(adc_num);
//        Serial.print(":");
//        Serial.print(*pbuffer);
//        Serial.print(",");
//        Serial.println(filterOutput);
//      }
//      
//      Serial.print("Pixelcounter:");
//        Serial.println(xPixelCounter[adc_num]);
//        Serial.print("pbuffer Value of ADC");
//        Serial.print(adc_num);
//        Serial.print(" is: ");
//        Serial.println(*pbuffer);
//        Serial.println(graphValuesADC[adc_num][xPixelCounter[adc_num]]);*/
//      xPixelCounter[adc_num]++;
//    }
//    //graphValuesADC1
//    //graphValuesADC2

    pbuffer++;
    counter++;
  }

  //use the halfs of the buffer interchangingly
  if (bufferHalfFilled == false){bufferHalfFilled = true;}
  else {bufferHalfFilled = false;}
  
  //Serial.println(micros()-microsFilter);

  //sd modifications after buffer loop completion
  if(writeRawDataToSD == true){
    myFile.println(); //new line
    myFile.flush();   //save bytes written
  }

  //Serial.printf(" %d - %u(%u): %u <= %u <= %u %d ", adc_num, pabdma->interruptCount(), pabdma->interruptDeltaTime(), min_val,
  //              average_value, max_val, rms);
  pabdma->clearInterrupt();

  pabdma->userData(average_value);
}
void initializeDAC() {  
  tft.print("Initializing DAC...");
  // DAC initiation
  dac.attatch(Wire, MCP4728_LDAC_PIN);
  dac.readRegisters();

  dac.selectVref(MCP4728::VREF::INTERNAL_2_8V, MCP4728::VREF::INTERNAL_2_8V, MCP4728::VREF::INTERNAL_2_8V, MCP4728::VREF::INTERNAL_2_8V); // use: VDD->VDD voltage, INTERNAL_2_8V->internal vref 2048V
  dac.selectPowerDown(MCP4728::PWR_DOWN::NORMAL, MCP4728::PWR_DOWN::NORMAL, MCP4728::PWR_DOWN::NORMAL, MCP4728::PWR_DOWN::NORMAL);        // can be used to reduce power consumption, normal mode uses about 1mA
  dac.selectGain(MCP4728::GAIN::X1, MCP4728::GAIN::X1, MCP4728::GAIN::X1, MCP4728::GAIN::X1);   // X1->2048mV, X2->4096mV(if VDD is higher)
  // set all channels to zero, before enabling the DAC:
  dac.analogWrite(MCP4728::DAC_CH::A, 0);
  dac.analogWrite(MCP4728::DAC_CH::B, 0);
  dac.analogWrite(MCP4728::DAC_CH::C, 0);
  dac.analogWrite(MCP4728::DAC_CH::D, 0);

  dac.enable(true);
  tft.println("done");
#ifdef DEBUG
  dac.readRegisters();
  Serial.println ("DAC initialized using follwing values:");
  DACprintStatus();
#endif
}
void setDAC(double A, double B, double C, double D) {
  dac.analogWrite(MCP4728::DAC_CH::A, uint16_t (A * 4095 + 0.5));
  dac.analogWrite(MCP4728::DAC_CH::B, uint16_t (B * 4095 + 0.5));
  dac.analogWrite(MCP4728::DAC_CH::C, uint16_t (C * 4095 + 0.5));
  dac.analogWrite(MCP4728::DAC_CH::D, uint16_t (D * 4095 + 0.5));
}
void DACprintStatus() {
  Serial.println("NAME     Vref  Gain  PowerDown  DACData");
  for (int i = 0; i < 4; ++i)
  {
    Serial.print("DAC");
    Serial.print(i, DEC);
    Serial.print("   ");
    Serial.print("    ");
    Serial.print(dac.getVref(i), BIN);
    Serial.print("     ");
    Serial.print(dac.getGain(i), BIN);
    Serial.print("       ");
    Serial.print(dac.getPowerDown(i), BIN);
    Serial.print("       ");
    Serial.println(dac.getDACData(i), DEC);

    /* DAC EEPROM not used
       Serial.print("EEPROM");
      Serial.print(i, DEC);
      Serial.print("    ");
      Serial.print(dac.getVref(i, true), BIN);
      Serial.print("     ");
      Serial.print(dac.getGain(i, true), BIN);
      Serial.print("       ");
      Serial.print(dac.getPowerDown(i, true), BIN);
      Serial.print("       ");
      Serial.println(dac.getDACData(i, true), DEC);*/
  }
  Serial.println(" ");
}
float calculateSlugspeed(float filteredValue, uint8_t adc_num) {
  /*calculating ADC frequency from expected speed from pump datasheet:
     minimum volume flow = 0,012 ml/min (1 rpm) -> 0,254647909 mm/s per pump --> 0,509295818
     maximum volume flow = 72 ml/min (6000 rpm) -> 1527,887454 mm/s per pump --> 3055,774907
  */
  //wait for the filter to produce good results
  static uint8_t calculateSlugspeedCounter [2];
  //save the extrema for calculating the speed
  static uint16_t minValue [2] = {0xffff, 0xffff};
  static uint16_t maxValue [2] = {0, 0};
  //start when max-min difference is high ennough
  static bool startCalculation [2] = {false, false};
  //frame counter for calculating the speed
  static uint32_t slugspeedFrameCounter [2] = {0, 0};
  // deviation of max-min value, to recognize phase change
  const float percentageOfDifference = 0.3;
  //frame array for saving the threshold value of adc0 and adc1 for calculating the speed
  static uint32_t speedFrame [2];
  //last speed frame to calculate phase percentage
  static uint32_t lastSpeedFrame [2] = {0,0};
  //array for saving the first threshold frame number
  static uint32_t speedCalcFrame [2];
  //frame counter when threshold is reached
  static uint16_t speedCalcFrameConfirmCounter [2] = {0, 0};
  //slugspeedCond1 is true, when adc0 was low and then passed 30% of difference to high
  static bool slugspeedCond1 = false;
  //speedCalcFrameConfirm becomes true when adc0/1 values passed threshold for 10ms
  static bool speedCalcFrameConfirm [2] = {false, false};
  //for counting up if it's constantly low long ennough
  static bool counterLowerADC0StartedCounting = false;

  //timer for max min reset, if nothing changes for too long
  static uint32_t resetMinMaxTimer = millis();

  static uint32_t counterLowerADC0 = 0;

  //variables for phase change:
  static bool phasePercentageFrameReady = false;
  static uint32_t phasePercentageFrame;

  //count every frame
  slugspeedFrameCounter [adc_num] ++;

  //reset max min if nothing happens for 10s or calc slugspeed is too high
  if (millis() - resetMinMaxTimer > 10000){
    resetMinMaxTimer = millis();
    minValue [0] = 0xffff;
    minValue [1] = 0xffff;
    maxValue [0] = 0;
    maxValue [1] = 0;
    startCalculation [0] = false;
    startCalculation [1] = false;
    slugspeedCond1 = false;
    speedCalcFrameConfirm [0] = false;
    speedCalcFrameConfirm [1] = false;
    counterLowerADC0StartedCounting = false;
  }

  //Find filtered global minimum and maximum for each ADC
  if (filteredValue < minValue [adc_num]) {
    minValue [adc_num] = filteredValue;
  }
  if (filteredValue > maxValue [adc_num]) {
    maxValue [adc_num] = filteredValue;
  }
  //get difference
  float maxMinDiff = maxValue [adc_num] - minValue [adc_num];
  /*Serial.print("ADC");
  Serial.print(adc_num);
  Serial.print(": min=");
  Serial.print(maxValue [adc_num]);
  Serial.print("    ADC");
  Serial.print(adc_num);
  Serial.print(": max=");
  Serial.print(maxValue [adc_num]);
  Serial.print("    max min difference:");
  Serial.println(maxMinDiff);*/
  //start calculation when max-min difference is high ennough
  if (startCalculation [adc_num] == false && maxMinDiff > 100) {
    startCalculation [adc_num] = true;
  }
  
  //return zero, if max-min difference is not high ennough
  if (startCalculation [0] == false || startCalculation [1] == false) {
    return 0;
  }

  //start couter, when ADC0 max-min is 30% higher than ADC0min
  /*  if ADC0 is lower than min + 30%max-min for nearly 10ms, flag1=true
      if flag1 == true and ADC0 is higher than min + 20%max-min, start counting
  */
  //start counting, when it's lower than min + 30% * minmax
  if (slugspeedCond1 == false && adc_num == 0){
   if (counterLowerADC0StartedCounting == false && filteredValue < float(minValue [adc_num]) + maxMinDiff*percentageOfDifference) {
      counterLowerADC0StartedCounting = true;
      phasePercentageFrame = slugspeedFrameCounter [0];
      counterLowerADC0 = 0;
    }
    //count up until 100ms
    else if (counterLowerADC0StartedCounting == true && filteredValue < float(minValue [adc_num]) + maxMinDiff*percentageOfDifference){
      counterLowerADC0 ++;
      if (counterLowerADC0 == ADC_frequency / 12){
        slugspeedCond1 = true;
        //Serial.println("slugspeedCond1 = true");
        counterLowerADC0 = 0; //reset counterLowerADC0
        return 0;
      }
    }
    //reset if when it's higher than min + 30% * minmax
    else if (counterLowerADC0StartedCounting == true && adc_num == 0 &&
              filteredValue > float(minValue [adc_num]) + maxMinDiff*percentageOfDifference) {
      counterLowerADC0StartedCounting = false;
    }
  }
  else if (slugspeedCond1 == true) {
    if (speedCalcFrameConfirm [0] == false){
        //if threshold of adc0 is reached, save the frame number of adc 0
      if (adc_num == 0 && speedCalcFrame[0] == false && filteredValue > float(minValue [adc_num]) + maxMinDiff*percentageOfDifference) {
        speedFrame [0] = slugspeedFrameCounter [0];
        speedCalcFrame [0] = true;
        //Serial.print("frame number of adc0 = ");
        //Serial.println(speedFrame [0]);
      }
      //if lower than threshold again, reset
      else if (adc_num == 0 && speedCalcFrame[0] == true && filteredValue < float(minValue [adc_num]) + maxMinDiff*percentageOfDifference) {
        speedCalcFrame [0] == false;
        speedCalcFrameConfirmCounter[0] = 0;  //reset counter
      }   
      //if it's 10ms above confirm speedCalcFrame
      else if (adc_num == 0 && speedCalcFrame[0] == true && filteredValue > float(minValue [adc_num]) + maxMinDiff*percentageOfDifference) {
        speedCalcFrameConfirmCounter[0]++;
        if (speedCalcFrameConfirmCounter [0] == ADC_frequency / 12) {
          speedCalcFrameConfirm [0] = true;    //confirm the saved frame
          speedCalcFrameConfirmCounter[0] = 0; //reset counter
          //Serial.println("speedCalcFrameConfirm is true");
        }
      }
    }    
      //if threshold of adc1 is reached, save the frame number of adc 1
    if (adc_num == 1 && speedCalcFrame[0] == true && speedCalcFrame[1] == false && filteredValue > float(minValue [adc_num]) + maxMinDiff*percentageOfDifference) {
      speedFrame [1] = slugspeedFrameCounter [1];
      speedCalcFrame [1] = true;
      //Serial.print("speedFrame adc1 is: ");
      //Serial.println(speedFrame [1]);
    }
    //if lower than threshold again, reset
    else if (adc_num == 1 && speedCalcFrame[0] == true && speedCalcFrame[1] == true && filteredValue < float(minValue [adc_num]) + maxMinDiff*percentageOfDifference) {
      speedCalcFrame [1] = false;
      speedCalcFrameConfirmCounter[1] = 0;
    }
    else if (adc_num == 1 && speedCalcFrame[0] == true && speedCalcFrame[1] == true && filteredValue > float(minValue [adc_num]) + maxMinDiff*percentageOfDifference) {
      speedCalcFrameConfirmCounter[1]++;
      //Serial.print("speedCalcFrameConfirmCounter of adc1 is: ");
      //Serial.println(speedCalcFrameConfirmCounter[1]);
      if (speedCalcFrameConfirmCounter [1] == ADC_frequency / 12) {
        //Serial.println("speedCalcFrameConfirmCounter of adc1 is confirmed");
        //reset all bools and the counter
        speedCalcFrameConfirm [0] = false;
        speedCalcFrame[0] = false;
        speedCalcFrame[1] = false;
        slugspeedCond1 = false;
        counterLowerADC0StartedCounting = false;
        speedCalcFrameConfirmCounter[0] = 0; //reset counter
        speedCalcFrameConfirmCounter[1] = 0;
        //calculate the slugspeed
        slugSpeed = distanceSensors / ((double(speedFrame [1] - speedFrame [0]) / double(ADC_frequency)) - double(initMicrosADC1)/1000000);
        //phase percentage calculation (done using sav golay filter, see "calculateSlugSpeedSavGol()"):
//        phasePercentage = (double(phasePercentageFrame - lastSpeedFrame [0])*100 / double(speedFrame [0] - lastSpeedFrame [0]));
        /*Serial.println(speedFrame [0]);
        Serial.println(lastSpeedFrame [0]);
        Serial.println(phasePercentageFrame);*/
        lastSpeedFrame [0] = speedFrame [0];
        newSlugspeedValueReadyForRegulation = true;
        newSlugspeedValueReadyForPrinting = true;
        newSlugspeedValueReadyForSD = true;
      }
    }
    //expectedMaxSpeed =
  }
}
void calculateSlugSpeedSavGol(){
  const uint16_t savGolBufferFPS = 160; //
  const uint16_t maxBufferTime = 10;    //seconds
  static float savGolBuffer [2] [savGolBufferFPS*maxBufferTime];
  static float minSavGol [2] = {0,0};
  static float maxSavGol [2] = {0,0};
  static uint16_t savGolBufferCounter = 0;
  static uint16_t savGolCounter = 0;
  static uint16_t savGolInfinityCounter = 0;
  static uint16_t riseFrame [2] [2] = {0,0,0,0};
  static uint16_t fallFrame [2] [2] = {0,0,0,0};
  static bool firstRun = true;
  static bool savGolMaxMinCond = false;
  static bool zeroed = false;
  static bool thresholdValueAvail = false;

  static uint32_t startSavGolTimer = millis();
  static uint32_t resetMinMaxTimer = millis();

  //reset max and min, if no value was calculated for 10 seconds:
  if (millis() - resetMinMaxTimer > 10000){
    resetMinMaxTimer = millis();
    savGolMaxMinCond = false;
    zeroed = false;
    thresholdValueAvail = false;
    minSavGol [0] = 0;
    minSavGol [1] = 0;
    maxSavGol [0] = 0;
    maxSavGol [1] = 0;
    //Serial.println("reset max min");
  }
//  if (millis()-startSavGolTimer > 500){
//    startSavGolTimer = millis();
//    tft.fillRect(0,200,320,40,ILI9341_BLACK);
//    tft.setCursor(0,200);
//    tft.println("  max    min    %  ");
//    tft.print(maxSavGol[0]);
//    tft.print("  ");
//    tft.print(minSavGol[0]);
//    tft.print("  ");
//    tft.println(savGolPhasePercentage);
//  }

  for (int i = 0; i<buffer_size ;i++){
    if (savGolCounter % (ADC_frequency/savGolBufferFPS) == 0){
      savGolInfinityCounter++;
      //Serial.println("1");
      ADC0SavLayValue = outputBuffer [0] [movAvg] [i];
      ADC1SavLayValue = outputBuffer [1] [movAvg] [i];
      savGolBuffer [0] [savGolBufferCounter] = filterADC0.Compute();
      savGolBuffer [1] [savGolBufferCounter] = filterADC1.Compute();
      
      //wait for the savGolFilter library buffer to fill:
      if (firstRun && savGolInfinityCounter == windowSize){
        firstRun = false;
      }
      else if (!firstRun){
        if (savGolBuffer [0] [savGolBufferCounter] < minSavGol [0]){minSavGol [0] = savGolBuffer [0] [savGolBufferCounter];}
        if (savGolBuffer [1] [savGolBufferCounter] < minSavGol [1]){minSavGol [1] = savGolBuffer [1] [savGolBufferCounter];}
        if (savGolBuffer [0] [savGolBufferCounter] > maxSavGol [0]){maxSavGol [0] = savGolBuffer [0] [savGolBufferCounter];}
        if (savGolBuffer [1] [savGolBufferCounter] > maxSavGol [1]){maxSavGol [1] = savGolBuffer [1] [savGolBufferCounter];}
      }

      //if min and max are big ennough, continue
      if (savGolMaxMinCond == false && maxSavGol [0] > 10 && minSavGol [0] < -10){
        //Serial.println("max min big ennough");
        savGolMaxMinCond = true;
      }
      else if (savGolMaxMinCond) {
        
        //if savGol filtered value is nearly 0, continue
        if (!zeroed && abs(savGolBuffer [0] [savGolBufferCounter]) <= 1) {
          //Serial.println("Nearly zero, so start");
          zeroed = true;
        }
        else if (zeroed){
          static float thresholdValue;
          static uint16_t savedCounterValue;
          static uint8_t counterRise0;
          static uint8_t counterFall0;
          static double tempMax [2] = {0,0};

          //if threshold is passed again, calculate the center of gravity
          if (thresholdValueAvail && thresholdValue > 0 && savGolBuffer [0] [savGolBufferCounter] < 0){
            riseFrame [0] [0] = riseFrame [0] [1];
//            Serial.print("SavGolBuffer = ");
//            Serial.print(savGolBufferCounter);
//            Serial.print(", savGolBuffer value 0 = ");
//            Serial.println(savGolBuffer [0] [0]);
            riseFrame [0] [1] = calculateCenterOfGravity (savGolBuffer [0], savGolBufferCounter) + savedCounterValue;
            thresholdValueAvail = false;
            savGolBufferCounter = 0;
            if (!(counterRise0 == 1)){
              counterRise0++;
            }
            else if (counterRise0 == 1 && counterFall0 == 1 && riseFrame [0] [0] < fallFrame [0] [1] && riseFrame [0] [1] > fallFrame [0] [1]){
              savGolPhasePercentage = 100-100*double(fallFrame [0] [1] - riseFrame [0] [0]) / double(riseFrame [0] [1] - riseFrame [0] [0]);
              phasePercentage = savGolPhasePercentage;
              resetMinMaxTimer = millis(); //reset reset-counter
            }
          }
          else if (thresholdValueAvail && thresholdValue < 0 && savGolBuffer [0] [savGolBufferCounter] > 0){
            fallFrame [0] [0] = fallFrame [0] [1];
            fallFrame [0] [1] = calculateCenterOfGravity (savGolBuffer [0], savGolBufferCounter) + savedCounterValue;
            thresholdValueAvail = false;
            savGolBufferCounter = 0;
            if (!(counterFall0 == 1)){
              counterFall0++;
            }
            else if (counterRise0 == 1 && counterFall0 == 1){
              //savGolPhasePercentage = 100*double(riseFrame [0] [1] - fallFrame [0] [0]) / double(fallFrame [0] [1] - fallFrame [0] [0]);
            }
          }
          
          //if savGol is positive and bigger than 0.1 * max
          else if (savGolBuffer [0] [savGolBufferCounter] > maxSavGol [0]*0.05){
            if (!thresholdValueAvail){
              thresholdValue = maxSavGol [0]*0.05;
              savedCounterValue = savGolInfinityCounter;
              thresholdValueAvail = true;
            }
            savGolBufferCounter++;
          }
          //if savGol is negative and smaller than 0.1 * min
          else if (savGolBuffer [0] [savGolBufferCounter] < minSavGol [0]*0.05){
            if (!thresholdValueAvail){
              thresholdValue = minSavGol [0]*0.05;
              savedCounterValue = savGolInfinityCounter;
              thresholdValueAvail = true;
            }
            savGolBufferCounter++;
          }
        }
      }

      savGolCounter = 0;
    }
    savGolCounter++;
  }
  
  
  //if buffer is filled without calculation, reset buffer
  if (savGolBufferCounter == savGolBufferFPS*maxBufferTime){
    savGolBufferCounter = 0;
  }
}
float calculateCenterOfGravity (float centerBuffer[], uint32_t numberOfValues) {
  float denom = 0;
  float nom = 0;
  for (int j = 0; j < numberOfValues; j++){
    denom += centerBuffer [j];
    nom += (j+1) * centerBuffer [j];
  }
  return nom / denom;
}
void graphPrintOnScreen() {
  static bool printingGraphJustStarted = true; // if graphPrinting just started
  static uint16_t speedMillis;
  if (displayPrinting == false || graphPrintDataReady == false) {
    return; //check if printing is enabled and if display data was written to buffer
  }
  //clean the screen and write Title on start:
  if (printingGraphJustStarted) {
    slugspeed:
    tft.setFont(DroidSansMono_12);
    tft.fillScreen(ILI9341_BLACK);
    tft.setCursor(0, 0);
    tft.setTextColor(ILI9341_GREEN);
    tft.print("Desired Slugspeed = ");
    tft.setCursor(320-10*characterWidth, 0);
    //tft.print(desiredSlugspeed, 1);
    tft.setCursor(320-4*characterWidth, 0);
    tft.print("mm/s");
    tft.setCursor(0, characterHeight);
    tft.setTextColor(ILI9341_CYAN);
    tft.print("Slugspeed = ");
    tft.setCursor(320-10*characterWidth, characterHeight);
    tft.print(slugSpeed, 1);
    tft.setCursor(320-4*characterWidth, characterHeight);
    tft.print("mm/s");
    //phase:
    tft.setCursor(0, 2*characterHeight);
    tft.setTextColor(ILI9341_ORANGE);
    tft.print ("Desired phase =");
    tft.setCursor(320-4*characterWidth, 2*characterHeight);
    tft.print ("%");
    tft.setCursor(0, 3*characterHeight);
    tft.setTextColor(ILI9341_OLIVE);
    tft.print ("Phase =");
    tft.setCursor(320-4*characterWidth, 3*characterHeight);
    tft.print ("%");

    printingGraphJustStarted = 0;
    speedMillis = millis(); //  millis for refreshing the written values
    //graphMicros = micros(); //  micros passed since last refresh
  }
  if (speedPrinting == true){
    speedMillis = millis();
    const uint8_t RefreshRate = 2; //hz
    static unsigned long startOfTimer = millis();
    if (newDesiredSlugspeedValueToPrintOnScreen == true) { //also prints phasePercentage due to simultanious calculation
      tft.setTextColor(ILI9341_GREEN);
      tft.fillRect(320-10*characterWidth, 0, 6*characterWidth, characterHeight, ILI9341_BLACK);
      tft.setCursor(320-10*characterWidth, 0);
      tft.print(desiredSlugspeed, 1);
      newDesiredSlugspeedValueToPrintOnScreen = false;
    }
    if (newSlugspeedValueReadyForPrinting){
      tft.setTextColor(ILI9341_CYAN);
      tft.fillRect(320-10*characterWidth, characterHeight, 6*characterWidth, characterHeight, ILI9341_BLACK);
      tft.setCursor(320-10*characterWidth, characterHeight);
      tft.print(slugSpeed, 1);
      tft.fillRect(320-10*characterWidth, 2*characterHeight, 6*characterWidth, characterHeight, ILI9341_BLACK);
      tft.setCursor(320-10*characterWidth, 2*characterHeight);
      tft.setTextColor(ILI9341_ORANGE);
      tft.print(desiredPhasePercentage,1);
      tft.fillRect(320-10*characterWidth, 3*characterHeight, 6*characterWidth, characterHeight, ILI9341_BLACK);
      tft.setCursor(320-10*characterWidth, 3*characterHeight);
      tft.setTextColor(ILI9341_OLIVE);
      tft.print(phasePercentage,1);
      startOfTimer = millis();
      newSlugspeedValueReadyForPrinting = false;
    }
  }
  if (doDisplayGraphPrinting == true){// && micros() - graphMicros >= graphTimeFrameMillis * 1000 / xDispResolution) {
    static uint32_t printGraphToDisplayCounter = 0;
    static uint16_t displayFullCounter = 0;
    const uint32_t displayGraphFrameInterval = ADC_frequency/xDispResolution*graphTimeFrameSecs;
    for (int i = 0; i<buffer_size ;i++){
      static uint16_t lastValuePrintedOnScreen [2] = {0,0};
      if (printGraphToDisplayCounter % displayGraphFrameInterval == 0){
        if (displayFullCounter == 0){
          lastValuePrintedOnScreen [0] = outputBuffer [0] [movAvg] [i];
          lastValuePrintedOnScreen [1] = outputBuffer [1] [movAvg] [i];
          displayFullCounter++;
          printGraphToDisplayCounter++;
          break;
        }
        tft.drawLine(displayFullCounter-1,uint16_t(graphHeight-(graphHeight * lastValuePrintedOnScreen [0]/4095+0.5))+4* characterHeight,displayFullCounter, uint16_t(graphHeight-(graphHeight * outputBuffer [0] [movAvg] [i]/4095+0.5))+4* characterHeight,ILI9341_WHITE);
        tft.drawLine(displayFullCounter-1,uint16_t(graphHeight-(graphHeight * lastValuePrintedOnScreen [1]/4095+0.5))+4* characterHeight,displayFullCounter, uint16_t(graphHeight-(graphHeight * outputBuffer [1] [movAvg] [i]/4095+0.5))+4* characterHeight,ILI9341_YELLOW);
        lastValuePrintedOnScreen [0] = outputBuffer [0] [movAvg] [i];
        lastValuePrintedOnScreen [1] = outputBuffer [1] [movAvg] [i];
        printGraphToDisplayCounter = 0;
        displayFullCounter++;
        if (displayFullCounter == xDispResolution){
            displayFullCounter = 0;
            tft.fillRect(0,yDispResolution-graphHeight,xDispResolution,graphHeight,ILI9341_BLACK);
        }
      }
      printGraphToDisplayCounter++;
    }
  }
}
float movingAverage(bool stopped, uint16_t rawValue, uint8_t adc_num) {
  static uint16_t movingAverageBuffer[2][maxMovingAverageWindowSize];
  static bool bufferFilled[2] = {false, false};
  static uint8_t movingAverageCounter [2] = {0, 0}; //counting through to know, which value to write
  uint32_t movingAverageSum = 0;
  float movingAverage;

  //reset buffer, if process is stopped
  if (stopped == true) {
    bufferFilled [0] = false;
    bufferFilled [1] = false;
    filterOutputReady = false;
    return 0;
  }

  //when buffer is filled, turn bool to true:
  if (bufferFilled [adc_num] == false && movingAverageCounter[adc_num] == movingAverageWindowSize - 1) {
    Serial.print("ADC");
    Serial.print(adc_num);
    Serial.println(" moving average buffer filled");
    bufferFilled [adc_num] = true;
  }

  //set global bool true, if moving average filter is ready
  if (bufferFilled [0]==true && bufferFilled [1]== true){
    filterOutputReady = true;
  }
  
  //fill buffer with current value:
  movingAverageBuffer[adc_num][movingAverageCounter[adc_num]] = rawValue;

  //when buffer is not filled, only devide sum of values by the number of values in the buffer (movingAverageCounter+1):
  if (bufferFilled [adc_num] == false) {
    for (int i = 0; i <= movingAverageCounter[adc_num]; i++) {
      movingAverageSum += movingAverageBuffer[adc_num][i];
    }
    movingAverage = float(movingAverageSum) / float(movingAverageCounter[adc_num] + 1);
  }
  //when buffer is filled, devide sum by movingAverageWindowSize
  else if (bufferFilled [adc_num] == true) {
    for (int i = 0; i < movingAverageWindowSize; i++) {
      movingAverageSum += movingAverageBuffer[adc_num][i];
    }
    movingAverage = float(movingAverageSum) / float(movingAverageWindowSize);
  }
  if (movingAverageCounter[adc_num] == movingAverageWindowSize - 1) {
    movingAverageCounter[adc_num] = 0;
  }
  movingAverageCounter[adc_num]++;
  //Serial.println(rawValue);
  //Serial.println(movingAverage);
  return movingAverage;
}
char * receiveSerialInput(bool & dataReady) {  //returns a pointer to a '\0' terminated string, if input is complete (only "\0" if not)
  static char nullChar [] = {'\0' };    // char to return, if nothing is ready
  if (Serial.available() > 0){
    //Serial.println("new Input");
    const static byte numChars = 32;             // maximum length of the input string
    static char receivedChars[numChars];  // array to store the received data 
    receivedChars[currentCharNumber] = Serial.read();
    if (receivedChars[currentCharNumber] == '\n') {    //if "enter" input was found
      receivedChars[currentCharNumber] = '\0';        // terminate the string
      currentCharNumber = 0;    //reset char number counter
      //dataReady = true;         //pass data available via reference
      //Serial.println(receivedChars);
      return receivedChars;     //return address of array 
    }
    else if (currentCharNumber >= numChars) {  //if input string is longer than array
      currentCharNumber = numChars - 1;   //just ignore the data and replace the last value
      return nullChar;
    }
    else {
      currentCharNumber++;  //count up
      return nullChar;
    }
  }
  return nullChar;        //return null if no data is ready
}
void processSerialInput (){
  //set desiredSlugspeed variable
  bool dataAvailable = false;
  char * data;
  float number;
  char letter [12];
  data = receiveSerialInput(dataAvailable);
  sscanf(data, "%2s%f", letter, &number);
  if (data != '\0'){
    if (strcmp(letter,"A") == 0){
      if (number > 3){
        //Serial.println("Choose an amperage lower than 3");
      }
      else{
        amperagePercentage = number/3; 
      }
    }
    else if (atof(data) <= 40){
      desiredSlugspeed = atof(data);
      newDesiredSlugspeedValueToPrintOnScreen = true;
      newDireredSlugspeedToRegulation = true;
    }
  }
}
void controlSlugspeed(){
  double inputDAC = pqFormula(regressionCurveCoeffs[2], upperLimitCalibrationCurve, desiredSlugspeed, regressionCurveCoeffs);
  if (inputDAC < 0) {
    inputDAC = 0;
  }
  else if (inputDAC > 0.4) {
    inputDAC = 0.4;
  }
  setDAC(float(inputDAC),float(inputDAC),0,0);
  y = inputDAC;
  newSlugspeedValueReadyForRegulation = false;
}
void printGraphToSerial(){
  if (doGraphPrintingToSerial){
    static uint32_t printGraphToSerialCounter = 0;
    for (int i = 0; i<buffer_size ;i++){
      if (printGraphToSerialCounter % graphFrameInterval == 0){
        ADC0SavLayForPrinting = outputBuffer [0] [movAvg] [i];
        ADC1SavLayForPrinting = outputBuffer [0] [movAvg] [i];
        double filteredADC0SavLayForPrinting = filterADC0ForPrinting.Compute()*20;
        double filteredADC1SavLayForPrinting = filterADC1ForPrinting.Compute()*20;
        
        Serial.print("ADC0: ");
        Serial.print(outputBuffer [0] [movAvg] [i]);
        Serial.print(" ADC1: ");
        Serial.println(outputBuffer [1] [movAvg] [i]);
        
        //Serial.print(" SavLayADC0:");
        //Serial.println(filteredADC0SavLayForPrinting+2000);
        printGraphToSerialCounter = 0;
      }
      printGraphToSerialCounter++;
    }
  }
}
void calibrateRegressionCurve (){
  bool startRecordingSpeed = false;
  double sum = 0;
  int j = 0;
  uint16_t counter = 1;
  double stepsize = 0.1;
  double i = stepsize;
  unsigned int long timerStart = millis();
  double curveCoeffPairs [2] [int(upperLimitCalibrationCurve/stepsize+1)];  // measured values ([0=x,1=y] [entry number])for regression curve calculation
  curveCoeffPairs [0] [0];
  curveCoeffPairs [1] [0];
  double singleValueArray [10];
  
  setDAC (i,0,0,0);
  Serial.print("Current DAC percentage: ");
  Serial.print(i*100);
  Serial.println(" %");
  Serial.print("Current slugspeed: ");
  while (i <= upperLimitCalibrationCurve){
    processADC();
    graphPrintOnScreen();
    // wait for the flow to settle:
    if (startRecordingSpeed == false && millis()-timerStart>= 3000){
      startRecordingSpeed = true;
      timerStart = millis();
    }
    // record slugspeed every 250ms
    else if (startRecordingSpeed == true && millis()-timerStart>= int(float(125/i))){
      timerStart = millis();
      sum += slugSpeed; // sum up slugspeeds
      Serial.print(slugSpeed);
      Serial.print("  ");
      j++;
      // if 8 values are measured, average them and save it to an array:
      if (j == 8){
        curveCoeffPairs [0] [counter] = i;
        curveCoeffPairs [1] [counter] = sum/8;
        Serial.println();
        Serial.print("Average slugspeed: ");
        Serial.print(curveCoeffPairs [1] [counter]);
        Serial.println(" mm/s");
        sum = 0;
        j = 0;
        startRecordingSpeed = false;  
        counter++;
        i = i+stepsize;
        timerStart = millis();
        setDAC (i,0,0,0);
        Serial.print("Current DAC percentage: ");
        Serial.print(i*100);
        Serial.println(" %");
        Serial.print("Current slugspeed: ");
      }
    }
    if (counter == int(upperLimitCalibrationCurve/stepsize+1)){
      setDAC (0,0,0,0);
      int ret = fitCurve(regressionCurveOrder, sizeof(curveCoeffPairs[0])/sizeof(double), curveCoeffPairs[0], curveCoeffPairs[1], sizeof(regressionCurveCoeffs)/sizeof(double), regressionCurveCoeffs);
      Serial.print("coefficients of regression curve: ");
      for (int j = 0; j < sizeof(regressionCurveCoeffs)/sizeof(double); j++){
        Serial.print(regressionCurveCoeffs[j]);
        Serial.print(", ");
      }
      Serial.println();
      Serial.println("Regression curve calculation done");
      EEPROM.put(8,regressionCurveCoeffs[0]);
      EEPROM.put(16,regressionCurveCoeffs[1]);
      EEPROM.put(24,regressionCurveCoeffs[2]);
      delay (3000);
    }
  }
  setDAC (0,0,0,0);
}
double pqFormula(double lowLimit, double upLimit, double y, double coeffs[]){ // coeffs: a,b,c (y=ax²+bx+c)  
  double x1 = (-coeffs[1]+(sqrt(sq(coeffs[1])-4*coeffs[0]*(coeffs[2]-y))))/(2*coeffs[0]);
  double x2 = (-coeffs[1]-(sqrt(sq(coeffs[1])-4*coeffs[0]*(coeffs[2]-y))))/(2*coeffs[0]);
  //Serial.println(x1);
  //Serial.println(x2);
  if (x1 <= upLimit && x1 >= lowLimit){
    return x1;
  }
  else if (x2 <= upLimit && x2 >= lowLimit){
    return x2;
  }
  else {
    return 0;
  }
}
void regulateSlugspeed(){
  double e = desiredSlugspeed - slugSpeed;
  static double esum = 0;
  static double last_e = 0;
  static bool desiredSlugspeedChanged = true;
  static double lastDesiredSlugspeed = -1;
  //to make it work, if the starting value is 0:
  if (lastDesiredSlugspeed != desiredSlugspeed){
    desiredSlugspeedChanged == true;
    //Serial.print("first time");
  }
  lastDesiredSlugspeed = desiredSlugspeed;
  if (desiredSlugspeed == 0){
    setDAC(0,0,0,0);
    return;
  }
  if (newSlugspeedValueReadyForRegulation || desiredSlugspeedChanged == true){
    kp = 0.000945;
    ki = 0.0039375;
    kd = 0.0002268;
    double workingPoint = 0.2;
    //Serial.print("Regulation: ");
    desiredSlugspeedChanged = false;
    esum += e;
    y = float(workingPoint + kp * e + ki * esum + kd * (e-last_e));
    last_e = e;
    //Serial.print("DAC input = ");
    //Serial.println(y);
    //don't go beyond working values:
    //Serial.println(y);
    if (y>=0.4)         {y=0.4;}
    if (y<=0 || y<=-0)  {y=0.075;}
    newSlugspeedValueReadyForRegulation = false;
    
    static double ph1 = 0.5;
    //only change DAC values, if new phase value is returned:
    static float y1 = y;
    static float y2 = y;
    double tempPh1 = -1;
    if (doPhaseRegulation == true){
      tempPh1 = regulatePhase ();
    }
    if (!(tempPh1 < 0)){ 
      ph1 = tempPh1;
    }
    y1 = 2*y*(1-ph1);
    y2 = 2*y-y1;
    setDAC(y1,y2,0,0);
    newSlugspeedValueReadyForRegulation = false;
  }
}
double regulatePhase (){
  const double kp_ph = 0.0028;
  const double ki_ph = 0.00062;
  const double kd_ph = 0;
  const double workingPoint = 0.5;
  static double esum = 0;
  static double last_e = 0;
  static uint32_t phaseTimer = millis();

  double tDelay = 250* 1000 / slugSpeed;
  if (millis() - phaseTimer > tDelay) {
    return -1;
  }
  phaseTimer = millis();
  
  double e = desiredPhasePercentage - phasePercentage;
  esum += e;
  double ph1 = workingPoint + kp_ph * e + ki_ph * esum;// + kd_ph * (e-last_e);
  last_e = e;
  if (ph1 >= 0.8){ph1=0.8;}
  else if (ph1 <= 0.2){ph1=0.2;}

  return ph1;
}
void modifySlugspeed(){
  static bool doRegulation = false;
  static double lastValue = -1;
  static unsigned long startModSlugTimer = millis();
  if (desiredSlugspeed != lastValue) {
    //controlSlugspeed();
    lastValue = desiredSlugspeed;
    doRegulation = false;
    startModSlugTimer = millis();
  } 
  else if (true){//doRegulation){
    regulateSlugspeed();
  }
  else if (millis() - startModSlugTimer >= int(15000/slugSpeed)){
    doRegulation = true;
  }
}
void startingQuestions (){
  double temp1, temp2, temp3;
  EEPROM.get(8,temp1);
  EEPROM.get(16,temp2);
  EEPROM.get(24,temp3);
  Serial.println("Load regression curve calibration? [y/n]");
  tft.println("Load regression curve calibration? [y/n]");
  Serial.println("EEPROM curve data is: ");
  Serial.print(temp1);
  Serial.print(", ");
  Serial.print(temp2);
  Serial.print(", ");
  Serial.println(temp3);
  tft.println("EEPROM curve data is: ");
  tft.print(temp1);
  tft.print(", ");
  tft.print(temp2);
  tft.print(", ");
  tft.println(temp3);
  while(true){
    if (Serial.available()){
      char c = Serial.read();
      if (c == 'y'){
        EEPROM.get(8,regressionCurveCoeffs[0]);
        EEPROM.get(16,regressionCurveCoeffs[1]);
        EEPROM.get(24,regressionCurveCoeffs[2]);
        break;
      }
      else if (c == 'n'){
        tft.fillScreen(ILI9341_BLACK);
        tft.setCursor(0, 0);
        Serial.println("Calibrate regression curve? [y/n]");
        tft.println("Calibrate regression curve? [y/n]");
        while(true){
          if (Serial.available()){
            char c = Serial.read();
            if (c == 'y'){
              calibrateRegressionCurve();
              break;
            }
            else if (c == 'n'){
              break;
            }
            while (Serial.available()){
              Serial.read();
              delay(2);
              }
            }
            delay (50);
          }
        break;
      }
      while (Serial.available()){
        Serial.read();
        delay(2);
      }
    }
    delay (50);
  }
}
void writeToSD(){
  if (doWriteToSD){
    /*static uint64_t writeToSDCounter = 0;
    //write all data to sd. Maybe later(for now, full blast 50secs max): Because Excel can only show 1.048.576 rows, writing 1.2khz (19,2khz/16, every 16th value) instead of 19.2khz, about 14 minutes and 30secs max.
    static bool headerIsWritten = false;
    //1st row:
    if (headerIsWritten == false){
      //write 1st row
      myFile.print("Date:");
      myFile.print(";");
      myFile.println("Datum hinzufügen");
      
      //write 2nd row
      for (int i = 0; i<6 ;i++){
        myFile.print(";");
      }
      myFile.print("ADC0");
      //Number of coulmns for the entries
      for (int i = 0; i<4 ;i++){
        myFile.print(";");
      }
      myFile.println("ADC1");

      //write 3rd row
      //global entries:
      myFile.print("Time");
      myFile.print(";");
      myFile.print("Time [ms]");
      myFile.print(";");
      myFile.print("Slugspeed");
      myFile.print(";");
      myFile.print("Phase1 [%]");
      myFile.print(";");
      myFile.print("Phase2 [%]");
      myFile.print(";");
      myFile.print("Phase3 [%]");
      myFile.print(";");

      //specific entries for each ADC:
      for (int i = 0; i<2 ;i++){
        myFile.print("Raw Data");
        myFile.print(";");
        myFile.print("Moving Average");
        myFile.print(";");
        myFile.print("1st Derivative");
        myFile.print(";");
        myFile.print("2nd Derivative");
        myFile.print(";");
      }
      myFile.println("");
      headerIsWritten = true;
    }
    //write from 4th row:
    for (int i = 0; i < buffer_size; i++){
      //print time, time[ms], Slugspeed, Ph1-3 percentage
      static const double msBetweenValues = 1000/double(ADC_frequency);
      myFile.print("time");
      myFile.print(";");
      myFile.print(double (writeToSDCounter)*msBetweenValues);
      myFile.print(";");
      myFile.print("slugspeed");
      myFile.print(";");
      myFile.print("Phase1 [%]");
      myFile.print(";");
      myFile.print("Phase2 [%]");
      myFile.print(";");
      myFile.print("Phase3 [%]");
      myFile.print(";");
      
      //print ADC0 values:
      //print raw, movAvg, 1st derivative, 2nd derivative
      myFile.print(outputBuffer [0] [raw] [i]);
      myFile.print(";");
      myFile.print(outputBuffer [0] [movAvg] [i]);
      myFile.print(";");
      myFile.print(outputBuffer [0] [derive1st] [i]);
      myFile.print(";");
      myFile.print(outputBuffer [0] [derive2nd] [i]);
      myFile.print(";");
      
      //print ADC1 values
      //print raw, movAvg, 1st derivative, 2nd derivative
      myFile.print(outputBuffer [1] [raw] [i]);
      myFile.print(";");
      myFile.print(outputBuffer [1] [movAvg] [i]);
      myFile.print(";");
      myFile.print(outputBuffer [1] [derive1st] [i]);
      myFile.print(";");
      myFile.println(outputBuffer [1] [derive2nd] [i]);
      writeToSDCounter++;
    }
    */
    for (int i = 0; i < buffer_size; i=i+2){
      //print time, time[ms], Slugspeed, Ph1-3 percentage
      static const double msBetweenValues = 1000/double(ADC_frequency);
      
      //print ADC0 values:
      //print raw, movAvg, 1st derivative
      myFile.print(outputBuffer [0] [raw] [i]);
      myFile.print(";");
      myFile.print(outputBuffer [0] [movAvg] [i]);
      myFile.print(";");
      myFile.print(outputBuffer [0] [derive1st] [i]);
      myFile.print(";");
      
      //print ADC1 values
      //print raw, movAvg, 1st derivative
      myFile.print(outputBuffer [1] [raw] [i]);
      myFile.print(";");
      myFile.print(outputBuffer [1] [movAvg] [i]);
      myFile.print(";");
      myFile.println(outputBuffer [1] [derive1st] [i]);
    }

    
    myFile.flush(); //to save the written values
  }
}
void toggleWriteToSD(){ //ISR
  doWriteToSD = !doWriteToSD;
  if (doWriteToSD == 1){
      tft.fillRect(300,220,20,20,ILI9341_GREEN);
    }
  else {
      tft.fillRect(300,220,20,20,ILI9341_RED);
    }  
}
void checkButtons(){
  //rotary encoder button:
  static unsigned int rotEncTimer = 0;
  if (millis() - rotEncTimer > 200){
    if (digitalRead(rotEncBtn) == 0){
      toggleWriteToSD();
      rotEncTimer = millis();
    }
  }
}
/*void print_ADC_debug_information(){
  // Lets again try dumping lots of data.
  Serial.println("\n*** DMA structures for ADC_0 ***");
  dumpDMA_structures(&(abdma1._dmachannel_adc));
  dumpDMA_structures(&(abdma1._dmasettings_adc[0]));
  dumpDMA_structures(&(abdma1._dmasettings_adc[1]));
  Serial.println("\n*** DMA structures for ADC_1 ***");
  dumpDMA_structures(&(abdma2._dmachannel_adc));
  dumpDMA_structures(&(abdma2._dmasettings_adc[0]));
  dumpDMA_structures(&(abdma2._dmasettings_adc[1]));

  #if defined(__IMXRT1062__)

  Serial.println("\n*** ADC and ADC_ETC ***");
  Serial.printf("ADC1: HC0:%x HS:%x CFG:%x GC:%x GS:%x\n", IMXRT_ADC1.HC0, IMXRT_ADC1.HS,  IMXRT_ADC1.CFG, IMXRT_ADC1.GC, IMXRT_ADC1.GS);
  Serial.printf("ADC2: HC0:%x HS:%x CFG:%x GC:%x GS:%x\n", IMXRT_ADC2.HC0, IMXRT_ADC2.HS,  IMXRT_ADC2.CFG, IMXRT_ADC2.GC, IMXRT_ADC2.GS);
  Serial.printf("ADC_ETC: CTRL:%x DONE0_1:%x DONE2_ERR:%x DMA: %x\n", IMXRT_ADC_ETC.CTRL,
                IMXRT_ADC_ETC.DONE0_1_IRQ, IMXRT_ADC_ETC.DONE2_ERR_IRQ, IMXRT_ADC_ETC.DMA_CTRL);
  for (uint8_t trig = 0; trig < 8; trig++) {
    Serial.printf("    TRIG[%d] CTRL: %x CHAIN_1_0:%x\n",
                  trig, IMXRT_ADC_ETC.TRIG[trig].CTRL, IMXRT_ADC_ETC.TRIG[trig].CHAIN_1_0);
  }
  #endif
  }
  /*void dumpDMA_structures(DMABaseClass *dmabc){
  Serial.printf("%x %x:", (uint32_t)dmabc, (uint32_t)dmabc->TCD);

  Serial.printf("SA:%x SO:%d AT:%x NB:%x SL:%d DA:%x DO: %d CI:%x DL:%x CS:%x BI:%x\n", (uint32_t)dmabc->TCD->SADDR,
                dmabc->TCD->SOFF, dmabc->TCD->ATTR, dmabc->TCD->NBYTES, dmabc->TCD->SLAST, (uint32_t)dmabc->TCD->DADDR,
                dmabc->TCD->DOFF, dmabc->TCD->CITER, dmabc->TCD->DLASTSGA, dmabc->TCD->CSR, dmabc->TCD->BITER);
  }*/

void setup() {
  asm(".global _sscanf_float");  // this makes sscanf to support float:
  pinMode(H2Switch, OUTPUT);
  pinMode(rotEncBtn, INPUT_PULLUP);
  
  initializeADC_and_Buffer();
  initializeTFT();
  //emptyGraphs();
  initalizeTouchscreen();
  tft.print("Waiting serial connection...");
  Serial.begin(9600); //baudrate ignored with teensy -> always 12mbit/s
  while (!Serial)// && millis() < 5000)
    delay(2000);
  Serial.println("Serial just started");
  tft.println("established");

  /*if (!loadTouchBordersFromEEPROM()) {
    calibrateTouchscreen (); // calibrate Touchscreen if no Borders are already saved
  }*/
  initalizeSD();


  // setting communication to i2C devices (DAC):
  tft.print("Initializing I2C connection...");
  Wire.begin(); // initialize i2c connection for MCP4728 DAC
  Wire.setClock(1000000);  // 100000 = standard mode (setDAC:3200µs), 400000 = Fast Mode (setDAC:947µs), 1.000.000 = maximum of wire library (setDAC:505µs), 2,4Mhz = high speed mode
  tft.println("done");
  initializeDAC();
  setDAC(0, 0, 0, 0);
  tft.print("Time to initiate ADC1: ");
  tft.print(initMicrosADC1);
  tft.println(" microseconds");
  tft.println();
  Serial.println("Setup done.");

  // questions about loading or doing regression curve calibration:
  //startingQuestions();
  if (doWriteToSD == 1){
      tft.fillRect(300,220,20,20,ILI9341_GREEN);
    }
  else {
      tft.fillRect(300,220,20,20,ILI9341_RED);
    }  
}

void loop() {
  processSerialInput ();
  checkButtons();
  setDAC(0, 0, 0, amperagePercentage);
  if (amperagePercentage == 0){
    digitalWrite(H2Switch, 0);
  }
  else{
    digitalWrite(H2Switch, 1);
  }
  processADC();
  //Serial.println(micros() - mics);
  
  //check if a new buffer is ready for printing:
  if (newGraphBufferFilled == true) {
    int timer = millis();
    printGraphToSerial();
    graphPrintOnScreen();
    //calculateSlugSpeedSavGol();
    writeToSD(); //must be checked: Too slow on teensy 3.6 at 19,2khz (about 120ms for 50ms period)
    newGraphBufferFilled = false;
    timer = millis()-timer;
    Serial.println(timer);
  }
  //modifySlugspeed();

}

Thought it's just my code, so i loaded the adc_timer_dma example. This compiles without a problem. But if I write "adc->adc0->startTimer(xxx)" with anything instead of xxx (even if nothing is in there), it compiles without complaint. This shouldn't happen I think? (and doesn't happen with the old ADC of 1.51, there it returns an error)

This code shouldn't compile:
Code:
/* Example for triggering the ADC with Timer using DMA instead of interrupts
    Valid for the current Teensy 3.x and 4.0.


  Timers:
    On Teensy 3.x this uses the PDB timer.

    On Teensy 4, this uses one or two of the unused QTimers.

    Setting it up:  The variables readPin must be defined for a pin that is valid for the first (or only)
    ADC.  If the processor has a second ADC and is enabled, than readPin2 must be configured to be a pin
    that is valid on the second ADC.

  DMA: using AnalogBufferDMA with two buffers, this runs in continuous mode and when one buffer fills
    an interrupt is signaled, which sets flag saying it has data, which this test application
    scans the data, and computes things like a minimum, maximum, average values and an RMS value.
    For the RMS it keeps the average from the previous set of data.
*/

#if defined(ADC_USE_DMA) && defined(ADC_USE_TIMER)

#include <ADC.h>
#include <DMAChannel.h>
#include <AnalogBufferDMA.h>

//#define PRINT_DEBUG_INFO

// This version uses both ADC1 and ADC2
#ifdef ADC_DUAL_ADCS
const int readPin_adc_0 = A0;
const int readPin_adc_1 = A2;
#else
const int readPin_adc_0 = A0;
const int readPin_adc_1 = 26;
#endif

ADC *adc = new ADC(); // adc object
const uint32_t initial_average_value = 2048;

extern void dumpDMA_structures(DMABaseClass *dmabc);
elapsedMillis elapsed_sinc_last_display;

// Going to try two buffers here  using 2 dmaSettings and a DMAChannel

const uint32_t buffer_size = 1600;
DMAMEM static volatile uint16_t __attribute__((aligned(32))) dma_adc_buff1[buffer_size];
DMAMEM static volatile uint16_t __attribute__((aligned(32))) dma_adc_buff2[buffer_size];
AnalogBufferDMA abdma1(dma_adc_buff1, buffer_size, dma_adc_buff2, buffer_size);

#ifdef ADC_DUAL_ADCS
DMAMEM static volatile uint16_t __attribute__((aligned(32))) dma_adc_buff2_1[buffer_size];
DMAMEM static volatile uint16_t __attribute__((aligned(32))) dma_adc_buff2_2[buffer_size];
AnalogBufferDMA abdma2(dma_adc_buff2_1, buffer_size, dma_adc_buff2_2, buffer_size);
#endif

void setup() {
  Serial.begin(9600);
  while (!Serial && millis() < 5000) ;

  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(readPin_adc_0, INPUT); // Not sure this does anything for us
  #ifdef ADC_DUAL_ADCS
  pinMode(readPin_adc_1, INPUT);
  #endif
  
  Serial.println("Setup both ADCs");
  // Setup both ADCs
  adc->adc0->setAveraging(8); // set number of averages
  adc->adc0->setResolution(12); // set bits of resolution
  #ifdef ADC_DUAL_ADCS
  adc->adc1->setAveraging(8); // set number of averages
  adc->adc1->setResolution(12); // set bits of resolution
  #endif

  // enable DMA and interrupts
  //Serial.println("before enableDMA"); Serial.flush();


  // setup a DMA Channel.
  // Now lets see the different things that RingbufferDMA setup for us before
  abdma1.init(adc, ADC_0/*, DMAMUX_SOURCE_ADC_ETC*/);
  abdma1.userData(initial_average_value); // save away initial starting average
#ifdef ADC_DUAL_ADCS
  abdma2.init(adc, ADC_1/*, DMAMUX_SOURCE_ADC_ETC*/);
  abdma2.userData(initial_average_value); // save away initial starting average
#endif
  //Serial.println("After enableDMA"); Serial.flush();

  // Start the dma operation..
  adc->adc0->startSingleRead(readPin_adc_0); // call this to setup everything before the Timer starts, differential is also possible
  adc->adc0->startTimer(a); //frequency in Hz

  // Start the dma operation..
#ifdef ADC_DUAL_ADCS
  adc->adc1->startSingleRead(readPin_adc_1); // call this to setup everything before the Timer starts, differential is also possible
  adc->adc1->startTimer(); //frequency in Hz
#endif

  print_debug_information();

  Serial.println("End Setup");
  elapsed_sinc_last_display = 0;
}

void loop() {

  // Maybe only when both have triggered?
#ifdef ADC_DUAL_ADCS
  if ( abdma1.interrupted() && (abdma2.interrupted())) {
    if ( abdma1.interrupted()) {
      ProcessAnalogData(&abdma1, 0);
    }
    if ( abdma2.interrupted()) {
      ProcessAnalogData(&abdma2, 1);
    }
    Serial.println();
    elapsed_sinc_last_display = 0;
  }
#else
  if ( abdma1.interrupted()) {
    ProcessAnalogData(&abdma1, 0);
    Serial.println();
    elapsed_sinc_last_display = 0;
  }
#endif
  if (elapsed_sinc_last_display > 5000) {
    // Nothing in 5 seconds, show a heart beat.
    digitalWriteFast(13, HIGH);
    delay(250);
    digitalWriteFast(13, LOW);
    delay(250);
    digitalWriteFast(13, HIGH);
    delay(250);
    digitalWriteFast(13, LOW);
    elapsed_sinc_last_display = 0;
  }
}

void ProcessAnalogData(AnalogBufferDMA *pabdma, int8_t adc_num) {
  uint32_t sum_values = 0;
  uint16_t min_val = 0xffff;
  uint16_t max_val = 0;

  uint32_t average_value = pabdma->userData();

  volatile uint16_t *pbuffer = pabdma->bufferLastISRFilled();
  volatile uint16_t *end_pbuffer = pbuffer + pabdma->bufferCountLastISRFilled();

  float sum_delta_sq = 0.0;
  if ((uint32_t)pbuffer >= 0x20200000u)  arm_dcache_delete((void*)pbuffer, sizeof(dma_adc_buff1));
  while (pbuffer < end_pbuffer) {
    if (*pbuffer < min_val) min_val = *pbuffer;
    if (*pbuffer > max_val) max_val = *pbuffer;
    sum_values += *pbuffer;
    int delta_from_center = (int) * pbuffer - average_value;
    sum_delta_sq += delta_from_center * delta_from_center;

    pbuffer++;
  }

  int rms = sqrt(sum_delta_sq / buffer_size);
  average_value = sum_values / buffer_size;
  Serial.printf(" %d - %u(%u): %u <= %u <= %u %d ", adc_num, pabdma->interruptCount(), pabdma->interruptDeltaTime(), min_val,
                average_value, max_val, rms);
  pabdma->clearInterrupt();

  pabdma->userData(average_value);
}

void print_debug_information()
{
#ifdef PRINT_DEBUG_INFO
  // Lets again try dumping lots of data.
  Serial.println("\n*** DMA structures for ADC_0 ***");
  dumpDMA_structures(&(abdma1._dmachannel_adc));
  dumpDMA_structures(&(abdma1._dmasettings_adc[0]));
  dumpDMA_structures(&(abdma1._dmasettings_adc[1]));
  Serial.println("\n*** DMA structures for ADC_1 ***");
  dumpDMA_structures(&(abdma2._dmachannel_adc));
  dumpDMA_structures(&(abdma2._dmasettings_adc[0]));
  dumpDMA_structures(&(abdma2._dmasettings_adc[1]));

#if defined(__IMXRT1062__)

  Serial.println("\n*** ADC and ADC_ETC ***");
  Serial.printf("ADC1: HC0:%x HS:%x CFG:%x GC:%x GS:%x\n", IMXRT_ADC1.HC0, IMXRT_ADC1.HS,  IMXRT_ADC1.CFG, IMXRT_ADC1.GC, IMXRT_ADC1.GS);
  Serial.printf("ADC2: HC0:%x HS:%x CFG:%x GC:%x GS:%x\n", IMXRT_ADC2.HC0, IMXRT_ADC2.HS,  IMXRT_ADC2.CFG, IMXRT_ADC2.GC, IMXRT_ADC2.GS);
  Serial.printf("ADC_ETC: CTRL:%x DONE0_1:%x DONE2_ERR:%x DMA: %x\n", IMXRT_ADC_ETC.CTRL,
                IMXRT_ADC_ETC.DONE0_1_IRQ, IMXRT_ADC_ETC.DONE2_ERR_IRQ, IMXRT_ADC_ETC.DMA_CTRL);
  for (uint8_t trig = 0; trig < 8; trig++) {
    Serial.printf("    TRIG[%d] CTRL: %x CHAIN_1_0:%x\n",
                  trig, IMXRT_ADC_ETC.TRIG[trig].CTRL, IMXRT_ADC_ETC.TRIG[trig].CHAIN_1_0);
  }
#endif
#endif
}

#ifdef PRINT_DEBUG_INFO
void dumpDMA_structures(DMABaseClass *dmabc)
{
  Serial.printf("%x %x:", (uint32_t)dmabc, (uint32_t)dmabc->TCD);

  Serial.printf("SA:%x SO:%d AT:%x NB:%x SL:%d DA:%x DO: %d CI:%x DL:%x CS:%x BI:%x\n", (uint32_t)dmabc->TCD->SADDR,
                dmabc->TCD->SOFF, dmabc->TCD->ATTR, dmabc->TCD->NBYTES, dmabc->TCD->SLAST, (uint32_t)dmabc->TCD->DADDR,
                dmabc->TCD->DOFF, dmabc->TCD->CITER, dmabc->TCD->DLASTSGA, dmabc->TCD->CSR, dmabc->TCD->BITER);
}
#endif

#else // make sure the example can run for any boards (automated testing)
void setup() {}
void loop() {}
#endif // ADC_USE_TIMER and DMA

I copied the ADC from the 1.51 folder to the new installation and it is working, but I would like to know, if I just get it wrong and my code is damaged or if it is really a problem with the ADC library.
 
Sounds like @pedvide maybe changed something in the library. I know at different times he was trying to remove stuff that was called at the higher level and the like.

You might try asking him up on github (i.e. raise an issue) and see.
 
Back
Top