Forum Rule: Always post complete source code & details to reproduce any issue!
Page 1 of 4 1 2 3 ... LastLast
Results 1 to 25 of 81

Thread: Teensyduino 1.54 Beta #12

  1. #1
    Administrator Paul's Avatar
    Join Date
    Oct 2012
    Posts
    404

    Teensyduino 1.54 Beta #12

    Here is an twelfth beta test for Teensyduino 1.54.

    This beta is meant as a 1.54 release candidate.


    Linux 32 bit:
    https://www.pjrc.com/teensy/td_154-b...nstall.linux32

    Linux 64 bit:
    https://www.pjrc.com/teensy/td_154-b...nstall.linux64

    Linux ARM:
    https://www.pjrc.com/teensy/td_154-b...stall.linuxarm

    Linux ARM64:
    https://www.pjrc.com/teensy/td_154-b...l.linuxaarch64

    MacOS 10.10 to 11.4:
    https://www.pjrc.com/teensy/td_154-b...S_Catalina.zip

    MacOS 10.8 to 10.14:
    https://www.pjrc.com/teensy/td_154-b...inoInstall.dmg

    Windows:
    https://www.pjrc.com/teensy/td_154-b...inoInstall.exe


    Changes since Teensyduino 1.54-beta11:

    Update NativeEthernet
    Add cmsis_gcc.h, for Arduino_TensorFlowLite library
    Fix Serial2 vs Serial4 on MicroMod (KurtE)
    Add SD library SdFat_Usage example
    Reduce CrashReport memory usage
    _VectorsRam change to volatile

  2. #2
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    14,439
    Win 10 install TD 1.54b12on IDE 1.8.15
    -> deleted hardware/teensy/avr to be sure it was clear of changed/orphaned files

    > No Block or Warn on Download or install
    > Working for compiles of LittleFS

    @Paul - is there a NULL CrashReport class for non_T_4.x/MM - to avoid build complaints?

  3. #3
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    8,605
    Quote Originally Posted by defragster View Post
    Win 10 install TD 1.54b12on IDE 1.8.15
    -> deleted hardware/teensy/avr to be sure it was clear of changed/orphaned files

    > No Block or Warn on Download or install
    Same here.

    Quote Originally Posted by defragster View Post
    @Paul - is there a NULL CrashReport class for non_T_4.x/MM - to avoid build complaints?
    Agreed, for backwards compatibility with Teensy 3 they should have a NULL CrashReport.

  4. #4
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    14,439
    For LittleFS Integrity Tests here are the No Edit No #ifdef versions for RAM and PSRAM :: Defragster/LittleFS/tree/main/examples/Integrity

    There are 977 lines in the FUNCTIONS.ino that are common helper func()'s. I did some minimal output adjustment and found a bug giving printf a 64 bit size but not a %llu.
    Code:
    :: /12_dir/X_file.txt   Verify /12_dir/X_file.txt 13800B  @KB/sec 2447.24 ----DEL---- -- X
    :: /12_dir/Y_file.txt   Verify /12_dir/Y_file.txt 14312B  @KB/sec 2447.33 ----DEL---- -- Y
    :: /12_dir/Z_file.txt   Verify /12_dir/Z_file.txt 14824B  @KB/sec 2492.27 ----DEL---- -- Z
    :: /12_dir/A_file.txt   Verify /12_dir/A_file.txt 7144B  @KB/sec 2375.79 ----DEL---- -- A
    :: /12_dir/B_file.txt  +++ size 0: Add 2536 @KB/sec 61.86 	  Verify /12_dir/B_file.txt 2536B  @KB/sec 1819.23
    :: /12_dir/C_file.txt  +++ size 0: Add 3048 @KB/sec 73.97 	  Verify /12_dir/C_file.txt 3048B  @KB/sec 1880.32
    :: /12_dir/D_file.txt  +++ size 0: Add 3560 @KB/sec 85.21 	  Verify /12_dir/D_file.txt 3560B  @KB/sec 2045.98
    :: /12_dir/E_file.txt  +++ size 0: Add 4072 @KB/sec 97.42 	  Verify /12_dir/E_file.txt 4072B  @KB/sec 2070.16
    The MEDIA specific ready to run code for RAM.ino and PSRAM.ino (opps it has 16MB at this time) should run on any system
    > Not sure if twin INO's is good to reduce what the user sees for quick testing? It seemed better for editing the variations versus the common functions.ino

    Some chatty comments added on the header - feedback or help welcome ...

    SPI and QSPI and MRAM will follow in the next 12 hrs ...

  5. #5
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    7,209
    Just installed over beta11 on IDE 1.8.15 with no issues, warnings or other blocking messages from windows or Norton. Again installed on Win10x64 Home Edition

    Ran @defragsters old LFSIntegrity sketch and verified that RAM disk does still work and retains the files on warm restart.

    Also, ran the newest SDCARD_Usuage sketch and works flawlessly - only tested with BUILTIN_SDCARD. Any yes for the BUILTIN_SDCARD only FIFO or DMA works

  6. #6
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    7,209
    Morning all again.

    I started putting together a readme for LittleFS, https://github.com/mjs513/LittleFS/tree/main, just started so not much there. So if you all have any suggestions let me know.

  7. #7
    Senior Member
    Join Date
    Apr 2014
    Location
    Cheltenham, UK
    Posts
    301
    I was under the understanding that SD could open more than 1 file at once. Currently it doesn't. See here https://forum.pjrc.com/threads/67609-Help-with-SD-Card
    It might be worth looking at before 1.54 goes live.

  8. #8
    Senior Member
    Join Date
    Apr 2014
    Location
    Cheltenham, UK
    Posts
    301
    Quote Originally Posted by BriComp View Post
    I was under the understanding that SD could open more than 1 file at once. Currently it doesn't. See here https://forum.pjrc.com/threads/67609-Help-with-SD-Card
    It might be worth looking at before 1.54 goes live.
    Forget what I said. I got it all wrong.
    Sorry!!

  9. #9
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    7,209
    @defragster - @Paul

    I just did a PR, https://github.com/PaulStoffregen/LittleFS/pull/14, that adds a quick and dirty readme to the LittleFS library and also added 2 examples from the SD library as well on usuage.

    Cheers

  10. #10
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,504
    Quote Originally Posted by mjs513 View Post
    Morning all again.
    I started putting together a readme for LittleFS, https://github.com/mjs513/LittleFS/tree/main, just started so not much there. So if you all have any suggestions let me know.
    That's a very clearly written readme. I like it a lot.

    You asked for suggestions, so here two remarks:
    • If you put a c++ after the three opening back ticks of a code section, gitHub will nicely color code it.
    • Right before the QSPI section an example showing how to "access or create files in the same manner as you would with an SD Card using the SD Library bundled with Teensyduio." might be helpful for those not so familiar with the SD card interface.

  11. #11
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    7,209
    Quote Originally Posted by luni View Post
    That's a very clearly written readme. I like it a lot.

    You asked for suggestions, so here two remarks:
    • If you put a c++ after the three opening back ticks of a code section, gitHub will nicely color code it.
    • Right before the QSPI section an example showing how to "access or create files in the same manner as you would with an SD Card using the SD Library bundled with Teensyduio." might be helpful for those not so familiar with the SD card interface.
    @luni - thanks for your suggestions. Will do, as soon as I give my aching fingers a rest

  12. #12
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    14,439
    Quote Originally Posted by mjs513 View Post
    @defragster - @Paul

    I just did a PR, https://github.com/PaulStoffregen/LittleFS/pull/14, that adds a quick and dirty readme to the LittleFS library and also added 2 examples from the SD library as well on usuage.

    Cheers
    Quote Originally Posted by luni View Post
    That's a very clearly written readme. I like it a lot.

    You asked for suggestions, so here two remarks:
    +1 on the readme and the samples.

  13. #13
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    14,439
    @mjs513 / @all - have you got an MRAM SPI chip online? If so can you give this a test? : Defragster/LittleFS/tree/main/examples/Integrity/MRAMSPI

    Any review notes for the code/comments ...

  14. #14
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    7,209
    @defragster
    Thanks. Figured it would help with your examples as well.

    Think I have add a few more notes in though on printing details for directory, memory usage and formatting. Need a break though

  15. #15
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    14,439
    Quote Originally Posted by mjs513 View Post
    @defragster
    Thanks. Figured it would help with your examples as well.

    Think I have add a few more notes in though on printing details for directory, memory usage and formatting. Need a break though
    Yes, it should after I get the 'mechancal' edits made for the Media types.

    Found my mounted SPI chips : PSRAM, FLASH ( plus PJRC board ) , MRAM. But I had a hand wired female plug socket to the ProtoSupplies SPI breakouts that were 'repurposed' - I need to find/replace to test any SPI. ... Found it on a T_4 on PJRC Purple Display board ... code dated : "LFSintegrity.ino Dec 15 2020"

    <EDIT> : NEW MRAMSPI sketch ran and found 7 month old data intact - and worked to extend - Need to drop sizes - 128KB fills quickly

  16. #16
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    24,468
    The new readme file looks great!

  17. #17
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    8,605
    Yes. Great readme :-)

  18. #18
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    9,214
    Quote Originally Posted by PaulStoffregen View Post
    The new readme file looks great!
    I will second or ... that... Looks great!

    I have installed this beta and tried the new sdfat_usage...
    Which worked for me

    Note on your usage of the ls function... Wonder if you should pass in some flags...

    Like I changed it when running it to: SD.sdfs.ls(LS_DATE | LS_SIZE);

    Output on mine now looks like:
    Code:
    Initializing SD card...initialization done.
    
    Print directory using SD functions
    System Volume Information/
    T4.1-Cardlike.jpg                         393481
    T4-Cardlike.jpg                           340510
    OV7670.bmp                                307266
    TL_01010003.tld                           1843200
    TL_01010005.tld                           22272000
    test1.txt                                 21
    datalog.bin                               41943040
    
    Print directory using SdFat ls() function
    2020-11-02 05:18     393481 T4.1-Cardlike.jpg
    2020-11-02 05:21     340510 T4-Cardlike.jpg
                         307266 OV7670.bmp
    2019-01-01 00:03    1843200 TL_01010003.tld
    2019-01-01 00:10   22272000 TL_01010005.tld
                             21 test1.txt
    2021-01-01 00:00   41943040 datalog.bin
    
    Writing to datalog.bin using SdFat functions
    datalog.bin started with 41943040 bytes
      Allocate 40 megabytes for datalog.bin
    Reading to datalog.bin using SD functions
      Read from file: Just some test data written to the file (by SdFat functions)
    Again so far everything is working that I tried on this build

  19. #19
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    7,209
    Quote Originally Posted by KurtE
    Like I changed it when running it to: SD.sdfs.ls(LS_DATE | LS_SIZE);
    Probably a good idea.

    And thanks all for the compliments but did not really do much except copy what we already put together in all the examples. Oh just one note, can't really add any more to readme - looks like there is a limit on the size unless I did something wrong.

  20. #20
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    14,439
    Posted LittleFS Examples/Integrity update on thread : pjrc.com/threads/58033-LittleFS-port-to-Teensy-SPIFlash

    Next is SPI after pushing cleanup on #4 back to the first 3 - then seems I need to Add PROG_MEM native FLASH example.

    And noted there - do I ifdef NAND .vs. NOR in same examples - or add two more variants? Simple variants allow 100% function without edit ( except SPI CS ).

  21. #21
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    14,439
    @Paul / @all: cleanup effort posted for LittleFS Integrity Media specific sketches

    See LittleFS-port-to-Teensy-SPIFlash

    Code:
    T:\arduino-1.8.15\hardware\teensy\avr\libraries\LittleFS\examples\Integrity>dir /b
    ALL
    MRAMSPI
    PROG
    PSRAM
    QSPI
    RAM
    SPI
    Help Re-Org:
    Code:
     1-9 '#' passes continue Loop before Pause
     'c, or 0': Continuous Loop, or stop Loop in progress
     'h, or k': start Hundred or Thousand Loops
     'd' Directory of LittleFS Media
     'D' Walk all Dir Files verify Read Size
     'l' Show count of loop()'s, Bytes Read,Written
     'B, or b': Make Big file half of free space, or remove all Big files
     'S, or s': Make 2MB file , or remove all 2MB files
     	>> Media Format : 'q' and 'F' remove ALL FS data
     'q' Quick Format Disk 
     'F' Low Level Format Disk 
     'w' WIPE ALL Directories and Files
     'm' Make ROOT dirs (needed after q/F format or 'w')
     'f' LittleFS::formatUnused( ALL ) : DATA PRESERVED, empty blocks preformatted 
     'a' Auto formatUnused() during Loop - TOGGLE
     'y' reclaim 1 block :: myfs.formatUnused( 1 )
     'Y' reclaim 15 blocks :: myfs.formatUnused( 15 )
     	>> Test Features 
     'g' run SpeedBench() Media speed benchmark
     'x' Directory filecount verify - TOGGLE
     'v' Verbose All Dir Prints - TOGGLE
     'p' Pause after all Dir prints - TOGGLE
     'n' No verify on Write- TOGGLE
     'u' Update Filecount
     'R' Restart Teensy - Except 'RAM' - data persists
     '+, or -': more, or less add .vs. delete in Loop
     '?' Help list : A Loop will Create, Extend, or Delete files to verify Integrity

  22. #22
    Member
    Join Date
    Mar 2021
    Location
    Germany
    Posts
    50

    NativeEthernet

    1.54 Beta 12 installed fine on clean new 1.8.15. However, it has not resolved one major problem: NativeEthernet's unreliability.


    Well, based on my experiments, I am inclined to say, that Teensy 4.1 is unsuitable for all applications which use Ethernet heavily as Ethernet processing stops after some time or crashes the processor completely from time to time. Of course, one can use Teensy 4.1's great watchdog to restart an application, when NativeEthernet has brought processing or it to a standstill, but this is not my understanding of a watchdog's real purpose. A real-time processing must run and not stall or restart frequently because of faulty code.

    If you scan the forum, you will find quite a few unresolved contributions, where users have described the fact that NativeEthernet is unreliable. Considering that Paul S. has written Arduino's great (new version 2) Ethernet library, I simply cannot comprehend, why there seems no obvious activity to get to the bottom of the issue. Of course, one could say, that Teensy 4.1 is hardware and all libraries are just "as they are", and therefore users have to accept that they might run out of luck, if a major feature isn't reliably working. However, why producing T4.1 over T4, if users cannot rely on its native Ethernet?


    Based on my trials, there are applications which can use NativeEthernet: these seem to be applications which either use just EthernetServer or EthernetClient and (!!!) have minimal Ethernet traffic. All others fail after a while, be it after a few minutes or hours.


    Let me explain in more depth, what I found so far: I have ported one application from Arduino Mega and two from Due to Teensy 4.1, all using a combination of EthernetServer and EthernetClient. One acts mainly as Server (with little traffic), connecting once every 10 mins to another T4.1 based Server as Client; the second is equally a Server with rare traffic, but connects once per minute as Client. The third, the one which makes me pulling out my hair, acts heavily as Server and as Client. The result: The first two rarely stop (but they stop), whilst the third crashes every few hours.

    I assumed that the error must be mine, ignoring the fact that basically the very same applications had successfully run for several years(!) non-stop and without any watchdog on Arduino Mega and Arduino Due. Well, in the end I have given up on the third one and ported it back to Arduino Due, where it now runs again since many days without any issue.


    Nevertheless, I wanted to understand the issue in more depth, and therefore made more investigations. I observed the following errors:

    a) EthernetServer stops, meaning T4.1 does no longer accept incoming requests, whilst outside calls are still working.
    b) the opposite, i.e. incoming calls are still served, whilst outgoing calls have stopped.
    c) T4.1 stops altogether (watchdog timeout >30secs)
    d) T4.1 can stop if the Sever, it connects to is restarted. It might have connected but awaits forever (> watchdog timeout) for an answer (no unprotected while() in my code!)

    In case a) and b) I have seen that NativeEthernet had run out of sockets, indication that the library's internal socket management has failed. Increasing the number of available sockets to 12 did not help, only delay the stall. In those cases c), I have seen happening, the socket count was below maxSocket.

    I have not been able to monitor all crashes as I did not look at USB Serial at all times. Important to note. I have very, very rarely seen SendErr:-20 in my applications, which all have been amended to make sure that all incoming data is read, client.close() and client.stop() are used.

    In order to get to the bottom, I have programmed an Arduino Due + Ethernetshield v2 to act as an EthernetServer and EthernetClient, the Client connection to a heating controller every 17seconds, from which it receives around 810bytes. Furthermore, I programmed an Arduino Mega + EthernetShield v2 to emulate a server, connecting to this T4.1. Whilst this is far from my real application, which exchanges traffic between many other Arduino and two Teensy 4.1 microcontrollers + a Windows Server, running several .aspx applications, it might be of help.

    All the Mega Client sends is "client.println("GET /PgEsNxx"); client.println();" with xx being 11, 22, 33....99. These 10 requests are made every 5 secs, 10ms apart. The burst of client.connects are made to simulate several requests, usually coming from different sources, but could of course coincide in time. This application performed perfectly without any issue on these Arduinos.


    In the next experiment I replaced the Due with a T4.1, and it became immediately obvious, that a too short time difference between two consecutive requests, lead to SendErr: -20, despite having made certain that T4.1 had read all incoming bytes and my application had run client.close() before client.stop(). I therefore increased the time between two requests to 50ms, although in real usage, when requests can come from different sources, this could not be guaranteed. Further investigation revealed that (one of) the problems seem to be, that T4.1 is very slow in answering a request - and not because it did not connect in time or was heavily loaded. Even allowing on the receiving server 25ms, there were occurrences where less than 10 bytes had been received. It wouldn't be too unexpected if some Server timed out, assuming that no more data was coming. Note in this case, that my application sends Data in client.print("abcd") packets and not in a buffer.

    As it seems to me - maybe this is too naively seen - the response is send out by T4.1 asynchronously with the application code, as the whole sending (in my example's code) takes less than 1ms. It might mean - I guess - that another Server response is has already started whilst the former connection is still being completed. Maybe this could explain the Socket miscount, I reported above?


    In cases, where T4.1 was unable to send all its information, it created those "SendErr: -20", which have been reported before. It means to me, that the fix to add client.close(), as suggested before, isn't the correct or only necessary fix. Basically, this error message appears if T4.1 cannot fully send its information. Whilst seeing message SendErr: -20 might be annoying, it simply reflects that the connecting client has given up before "slow" T4.1 has completed it's sending. Considering the tiny workload of my example, I think, it shouldn't take T4.1 so long to send out a few bytes. Having said all this, as said above, SendErr:-20 are not seen in my real applications, so they are not the (main) culprit in my application.


    Having added a sufficient long waiting at the Client, I got rid of most SendErr:-20, but unfortunately, as in my real applications, T4.1 stopped completely after approx. 90mins for the first. Something which could be repeated.
    Next I disabled (commented out sendPowerToMYPV2(0,500); )the use of EthernetClient to make it easier for you to reproduce the error. It still stalls the T4.1 albeit it takes much more time before the T4.1 stalls. In these experiments, one can see, how the SocketNumber slowly increases.
    Example: at start and 3.25h later

    07:14:54.266 -> GETPgEsN66 Action:20 SkNr@Start:0 additional Info rxed: = None client.close done SNrP1:0 client.stop executed SkNr@End:8 dt_ms: 0

    10:28:15.652 -> GETPgEsN66 Action:20 SkNr@Start:4 additional Info rxed: = None client.close done SNrP1:4 client.stop executed SkNr@End:8 dt_ms: 0


    Looking at everything, the clue might be the processing of requests which are close together in time, considering that the process partially takes place at different places of T4.1!? And as it seems, using EthernetClient whilst receiving several incoming requests close together in time, might cause the error more frequently.



    Teensy 4.1 is a great controller, at least in instances where no Ethernet or rare Ethernet is required. It might be a little heavy on RAM usage compared to Arduino Due, but that might be due to its relative new existence. I truly hope, PJRC undertakes effort to resolve the weakness of T4.1 Ethernet library as at present, it cannot challenge "old" Arduino Due when it comes to "heavier" Ethernet work.

    Please do not get me wrong: I truly appreciate the hard work which has gone into NativeEthernet or indeed any other software, but I see Ethernet as one key feature of T4.1 and therefore -in my opinion- already too much time has passed without experts' assistance and contribution to this multiple reported weakness. We, users of Teensy are not necessarily the experts who are albe to dive deep into complex libraries, particularly those which are close to Teensy's core architecture. Well, we might even be at fault, when we merely pass our experience from Arduino into Teensy, but that too means, we need experts' assistance.

    P.S. don't be surprised to see many "unused" variables in my code, that code is a snippet out of a rather lengthy application. It should hopefully help to reproduce the issue.

    Here is the T4.1 code
    Code:
    #define useClientClose 1
    
    #include <Wire.h>
    #include <SPI.h>
    #include <NativeEthernet.h>
    
    #include <elapsedMillis.h>
    
    #include <TimeLib.h>
    
    byte mac[] = {0xA8, 0x61, 0x0A, 0xAE, 0x2A, 0x1B };
    
    IPAddress ip(192, 168, 2, 11);
    IPAddress gateway(192,168,2, 1);
    IPAddress subnet(255, 255, 255, 0);
    
    EthernetServer server(9010);
    
    
    //IGNORE the following parameters, they remain here, as I cut this software from my major lengthy application
          int PowerHeliotherm=0;
          boolean allowThorAlways=true;
          unsigned long PowerDownThorAsLongNoActivity=0;
          int min_MYPV_Power_On=30;
          float factorThor=0.862;
          int ThorAskedNothing=0;                                 
          int max_ThorAskedNothing=240;                       
          float Parameter[275];
          int ParameterNrDerPowerForTHOR=0;
          boolean PowerThorUpAsThorWantsToWork=false;
          boolean bDruck_sendPowerToMYPV=true;
          int ErrorCounterACThor=0;                                
          int maxErrorCounterACThor=125;                           
          boolean ConnectionToThorOK=true;
          float LastThorPowerSent=0;                               
          boolean GotAZeroBackFromThor=true;
          int powerSentToThorSinceLastContactToPC=0;                  
          int AnzahlDerMessungen=0;                                   
          int HelioAlert=0;
          int LEDred=13;
          int LEDyellow=14;
          unsigned long LEDred_maxOn=1000;
          boolean showThorDetails=true;
          unsigned long Jetzt=0;
          byte OutBuffer[45];
          unsigned long Zeit_topowerDOWN_LEDyellow_PCC=0;
          unsigned long timeLastPC_Contact_Request_made=0;
          int counter_ServerContactLastMinute=0;
          const byte showDataExchangeToRx          =0;  //zeigt Main Kommunikation mit PC geschickt wird 
          const byte showDataExchangeToRx2         =0;  //zeigt Rest Kommunikation mit PC geschickt wird 
          const byte showDataExchangeToRxText      =0;  //zeigt Datenn die zum PC geschickt wird 
          const byte maxPowerMeasurements=10;
          float fPges[1441][maxPowerMeasurements];    
          boolean firstPges[maxPowerMeasurements]={false, false, false, false, false, false, false, false, false, false};  
          boolean ItsMidNight[maxPowerMeasurements]={false, false, false, false, false, false, false, false, false, false}; 
          unsigned int dayCounter[maxPowerMeasurements]={0,0,0,0,0,0,0,0,0,0};
          int NrAtMidNight[maxPowerMeasurements]={9999,9999,9999,9999,9999,9999,9999,9999,9999,9999};                
          boolean NotFirstLoop=false;
          float old_Ehour[maxPowerMeasurements]    = {9999,9999,9999,9999,9999,9999,9999,9999,9999,9999};
          float old_Eday[maxPowerMeasurements]     = {9999,9999,9999,9999,9999,9999,9999,9999,9999,9999};
          float old_Eweek[maxPowerMeasurements]    = {9999,9999,9999,9999,9999,9999,9999,9999,9999,9999};
          float old_Emonth[maxPowerMeasurements]   = {9999,9999,9999,9999,9999,9999,9999,9999,9999,9999};
          float Estunde[24][maxPowerMeasurements];  //hier speichern wir die stündlichen Summen ab
          float old_Estunde[24][maxPowerMeasurements];  //hier speichern wir die stündlichen Summen ab
          int counterEstunde[maxPowerMeasurements]={0,0,0,0,0,0,0,0,0,0};
          int counterEtag[maxPowerMeasurements]={0,0,0,0,0,0,0,0,0,0};
          int ErrorCounter[maxPowerMeasurements]={0,0,0,0,0,0,0,0,0,0};
          int old_ErrorCounter[maxPowerMeasurements]={0,0,0,0,0,0,0,0,0,0};
          float Etag[maxPowerMeasurements];           //hier speichern wir die laufende Tagessumme ab, dh Summe aller Messwerte durch Anzahl der Messwert
          float oldEtag[maxPowerMeasurements];        //hier den gestrigen Wert, so dass wir ihn nach Miternacht für 24 Stunden abrufen können
          byte letzteStunde=26;
          byte dieseStunde =25;
          boolean fPgesMemoryOverflow[maxPowerMeasurements]={false, false, false, false, false, false, false, false, false, false};
          boolean old_fPgesMemoryOverflow[maxPowerMeasurements]={false, false, false, false, false, false, false, false, false, false};
          byte ConversionLfdNrZuParameterNr[maxPowerMeasurements]={0,1,2,15,16,17,18,35,36,37};
          float LastPowerMeasurement[maxPowerMeasurements];
          float AverageBezug1Minute=0;   int CountBezug1Minute=0;
          float AverageLieferung1Minute=0;  int CountLieferung1Minute=0;
          float lastAverageBezug1Minute=0;  
          float lastAverageLieferung1Minute=0;  
          int EndSwitches=10;
          int startCO2=15;
          int SendErrorMsg1=5;
          int SunRiseMinAfterMidnight=400;
          int SunSetMinAfterMidnight=800;
          int ThorStatusForPrintInClock=0;
          int PowerUsedByMYPV=3459;
          int max_MYPV_Power_Used=3500;
          float T_wellness_1=38;
          float T_wellness_2=39.5; 
          float Vbat_Wellness=4.55;
          int NewInfoType=2;
          int WasserVerbrauchToday=850;
          byte KlimaOnOff=1;
          float  oldGeniaxKorrekturSimple=21;
          float GeniaxKorrekturSimple=21.5;
          byte cVorne_GeniaxKorrekturSimple  = 0;
          byte cHinten_GeniaxKorrekturSimple =0;
          byte cVorne_GeniaxKorrekturComplex  = 0;
          byte cHinten_GeniaxKorrekturComplex =0;
          float oldGeniaxKorrekturComplex=0;
          float GeniaxKorrekturComplex=0;
          int SolarPowerNow=0;
          unsigned long Left_PC_Contact=0;
          unsigned long timeOutCall=0;
          boolean useClientClose_PC_Contact=true;
                  
                 
    void setup() 
    {
       Serial.begin(250000);
    
        //Ignore these inits, they are caused by my snippet
        OutBuffer[ 0]=0x47; OutBuffer[ 1]=0x45; OutBuffer[ 2]=0x54; OutBuffer[ 3]=0x20; OutBuffer[ 4]=0x2F; OutBuffer[ 5]=0x63; OutBuffer[ 6]=0x6F; OutBuffer[ 7]=0x6E; OutBuffer[ 8]=0x74; OutBuffer[ 9]=0x72;        //GET /contr
        OutBuffer[10]=0x6F; OutBuffer[11]=0x6C; OutBuffer[12]=0x2E; OutBuffer[13]=0x68; OutBuffer[14]=0x74; OutBuffer[15]=0x6D; OutBuffer[16]=0x6C; OutBuffer[17]=0x3F; OutBuffer[18]=0x70; OutBuffer[19]=0x6F;        //ol.html?po
        OutBuffer[20]=0x77; OutBuffer[21]=0x65; OutBuffer[22]=0x72; OutBuffer[23]=0x3D; 
        Parameter[0]=1;
        pinMode(LEDred,OUTPUT); 
        pinMode(LEDyellow,OUTPUT); 
       
      
        Serial.println(F("connecting to Ethernet"));
                           
        pinMode(4,OUTPUT); digitalWrite(4,HIGH);
        Ethernet.begin(mac, ip, gateway, subnet);
    
        //server.begin();      //start listening for clients on EThernet         
    
         delay(1000);
      
    }
    
    void loop() 
    {
       if(millis()-timeOutCall>17000)
       {
    
          //sendPowerToMYPV2(0,500);          
          
          timeOutCall=millis();
       }
    
       PCContact();
       
       delay(1);
       
    }
    
    //--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    void PCContact()
    {   
              char ReadText[120];    
              byte Count=0;
              byte Action=99; 
    
          
              long t1=millis(); 
        
                  Ethernet.setRetransmissionCount(1);    //<------------------------------------------------------------------------------------------------------------------- 
                  Ethernet.setRetransmissionTimeout(50); //<-------------------------------------------------------------------------------------------------------------------
    
                  EthernetClient client = server.available();
     
                  client.setConnectionTimeout(25); 
    
                  boolean ExtraLine=false;
     
     
      
      
      if (client) 
      {
               
      
               //wait for Data from client   
               elapsedMillis waitPC1; 
    
               //wait for Server to connect      
               while(!client.available() && waitPC1 < 10000)
               {
                 delayMicroseconds(1);
    
                 if(waitPC1>16 && waitPC1%16==0) checkSerial1_for_KNX(); 
               }
      
               if(waitPC1 > 1000) {Serial.print("waitPC1: "); Serial.print(waitPC1); Serial.print("\tBytes:"); Serial.println(client.available());}     //INFO ONLY
               
                                                           
             
                        
                    if (client.available())
                    { 
                          Serial.println();
                          
                          while(client.available() && Count<95 )
                          {
                               ReadText[Count] = client.read();
                                           if(ReadText[Count]>48) Serial.print(ReadText[Count]);            
                               Count++;
                          }
                                     
                
                                            
                                         
                              
                                       if(ReadText[0]=='G' && ReadText[1]=='E' && ReadText[2]=='T') 
                                       {  
                                         
                                            Action = AnalyseGet(ReadText);     //Decode Get Information
                                        
                                            boolean currentLineIsBlank = true;
                                           
                                            int Limiter=0;
                                            
                                                   
                                                         
                                                        //In case we haven't already read everything                                      
                                                        while(client.available() && Limiter<120) 
                                                        {
                                                          char c = client.read();   Serial.print(c);             // see what has been received     
                                                              
                                                           if (c == '\n')
                                                           {   
                                                                currentLineIsBlank = true;      // you're starting a new line
                                                            }
                                                            else if (c != '\r')
                                                            { 
                                                                currentLineIsBlank = false;     // you've gotten a character on the current line
                                                            }
                        
                                                            if (c == '\n' && currentLineIsBlank) break;
                                                              
                                                            Limiter++; 
                                                            
                                                        } 
                                                        
                                                                                   
                                                      //Response - usually this connection goes to a true HTTP Server                                                                                                                                         
                                                                                                                                                                     
                                                      client.println(F("HTTp/1.1 200 OK")); client.println(F("Content-Type: text/html")); client.println(F("Connnection: close")); client.println();
    
                                                                           
                                                     
                                                      Serial.print("\tAction:"); Serial.print(Action); byte SockNr = client.getSocketNumber();  Serial.print("\tSkNr@Start:"); Serial.print(SockNr);                  
    
                                                     
                                                     switch (Action) 
                                                     {
                                                       
                                                        //----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
                                                        case 0: //Info not understood
                                                        {
                                                           Serial.print(F("\n\n\tCannot decode PC's GET Request. RXed:   ")); Serial.print(ReadText); Serial.print(F("  Count="));Serial.println(Count);
                                                           client.println(F("NOK"));
                                                           break;
                                                        }
    
                                                                                                          
                                                        //----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
                                                        case 99: //favicon - nothing to do
                                                        {
                                                          Serial.println(F("Favicon"));
                                                          break;
                                                        }
    
                                                       
                                                        //====================================================================================================================================================================
                                                        case 20: //sende Pges Daten an den PC
                                                        {
                                                                   //There is nothing special about this case 20, it has been stripped from my major application for this test - it basically sends 
                                                                   //in this test example : 0$0.00$0.00$0.00$0.00$0$27$53$1$1$1970$0$0.00$0$0.00$0.00$DATA$DATA
                                                                   
                                                                   
                                                                   //   else if(ReadText[5]=='P' && ReadText[6]=='g' && ReadText[7]=='E' && ReadText[8]=='s' && ReadText[9]=='N')                       bReturn=20;   //Messwerte der letzten Zeit senden
                  
                                                                   //GET /PgEsNpq_FabcdTvxyz$VAB$
                                                                   //012345678901234567890123
                                                                   
                                                                  
                                                                   if(ReadText[10]!=ReadText[11] || ReadText[10]<48 || ReadText[10]>57) {Serial.print(F("Invalid Request: ")); Serial.println(ReadText); break;}
                  
                  
                                                                   int PNr= ReadText[10] -48; 
                                                                      
                                                                   int StartIndex=0; int EndIndex=dayCounter[PNr]; 
                          
                                                                   //bei partieller Anfrage gilt GET /PgEsNpq_FabcdTvxyz$VAB$
                                                                   //                            012345678901234567890123
                                                                   //                            p=q  ParameterNr
                                                                   //                                         FROM
                                                                   //                                              To    .it VAB=V-1 für gestern
    
                                                                   if(PNr==9) ExtraLine=true;
                                                            
                                                         
                                                           if(ReadText[13]=='F' &&  ReadText[18]=='T' && ReadText[23]=='$')
                                                           { 
                                                               int S=0;
                                                               int E=  dayCounter[PNr];
                                                              
                                                              //partielle Anfrage
                                                              if(   (ReadText[14]=='0' || ReadText[14]=='1') && ReadText[15]>=48 && ReadText[15]<=57 && ReadText[16]>=48 && ReadText[16]<=57 && ReadText[17]>=48 && ReadText[17]<=57)
                                                              {
                                                                  S = (ReadText[14]-48)*1000 + (ReadText[15]-48)*100 + (ReadText[16]-48)*10 + (ReadText[17]-48); 
                                                               
                                                              }
                                                              else
                                                              {
                                                                //Serial.print(F("14 15 16 17: ")); Serial.print(ReadText[14]); Serial.print(ReadText[15]); Serial.print(ReadText[16]); Serial.println(ReadText[17]); 
                                                              }
                                                                  
                  
                                                                     
                                                                      if(ReadText[19]!='x' ||  ReadText[20]!='x' || ReadText[21]!='x' || ReadText[22]!='x' )
                                                                      {  
                                                                        if( (ReadText[19]=='0' || ReadText[19]=='1') && ReadText[20]>=48 && ReadText[20]<=57 && ReadText[21]>=48 && ReadText[21]<=57 && ReadText[22]>=48 && ReadText[22]<=57 )
                                                                        {
                                                                          E = (ReadText[19]-48)*1000 + (ReadText[20]-48)*100 + (ReadText[21]-48)*10 + (ReadText[22]-48); 
                                                                        }
                                                                      }
                                                                          else
                                                                      {
                                                                        //Serial.print(F("19 20 21 22: ")); Serial.print(ReadText[19]); Serial.print(ReadText[20]); Serial.print(ReadText[21]); Serial.println(ReadText[22]); 
                                                                      }
                                                                      
                      
                                                                                if(E>=S)
                                                                                { 
                                                                                   StartIndex=S; EndIndex=E;
                                                                                }
                                                                                else
                                                                                {
                                                                                  //Serial.print(F("E: ")); Serial.print(E); Serial.print(F("  S: ")); Serial.println(S);
                                                                                }
                  
                                                                  
                                                           }
                                                           else
                                                           {
                                                            //Serial.print(F("13 18 23: ")); Serial.print(ReadText[13]); Serial.print(ReadText[18]); Serial.println(ReadText[23]); 
                                                            
                                                           }
                                                           
                  
                                                         
                                                            //Serial.print(F("Pges["));  Serial.print(PNr); Serial.print(F("] -> PC   from: ")); Serial.print(StartIndex); Serial.print(F(" to ")); Serial.print(EndIndex); 
                  
                                                            
                                                           if(ReadText[24]=='V' && ReadText[25]=='-' && ReadText[26]=='1' )
                                                           {
                                                               client.print(dayCounter[PNr]); client.print(F("$"));
                                                              
                                                               client.print(Parameter[267]); client.print(F("$"));
                                                               client.print(Parameter[268]); client.print(F("$"));
                                                               client.print(Parameter[269]); client.print(F("$"));
    
                                                               
                                                               client.print(LastPowerMeasurement[PNr]); client.print(F("$"));
                                                               client.print(hour()); client.print(F("$"));
                                                               client.print(minute()); client.print(F("$"));
                                                               client.print(second()); client.print(F("$"));
                                                               client.print(day()); client.print(F("$"));
                                                               client.print(month()); client.print(F("$"));
                                                               client.print(year()); client.print(F("$"));
                      
                                                               client.print(counterEstunde[PNr]); client.print(F("$"));
                                                               client.print(Estunde[letzteStunde][PNr]); client.print(F("$"));
                                                                  
                                                               client.print(counterEtag[PNr]); client.print(F("$"));
                                                               client.print(Etag[PNr]); client.print(F("$"));
                                                               client.print(Parameter[EndSwitches+1]);                                                 
                                                               client.print(F("$DATA$"));
                                                               
                      
                      
                                                                                                        
                                                               for (int i=StartIndex; i< EndIndex; i++)
                                                               {
                                                                 client.print(F("$"));
                      
                                                                 if(i%100==0) checkSerial1_for_KNX();
                                                               }
                      
                                                               client.print(F("DATA"));
                                                           }
                                                           else
                                                           {
                                                                    client.print(dayCounter[PNr]); client.print(F("$"));
                                                                    client.print(Parameter[267]); client.print(F("$"));
                                                                    client.print(Parameter[268]); client.print(F("$"));
                                                                    client.print(Parameter[269]); client.print(F("$"));
                                                                   
                                                                   client.print(LastPowerMeasurement[PNr]); client.print(F("$"));
                                                                   client.print(hour()); client.print(F("$"));
                                                                   client.print(minute()); client.print(F("$"));
                                                                   client.print(second()); client.print(F("$"));
                                                                   client.print(day()); client.print(F("$"));
                                                                   client.print(month()); client.print(F("$"));
                                                                   client.print(year()); client.print(F("$"));
                      
                                                                   client.print(counterEstunde[PNr]); client.print(F("$"));
                                                                   client.print(Estunde[letzteStunde][PNr]); client.print(F("$"));
                                                                  
                                                                   client.print(counterEtag[PNr]); client.print(F("$"));
                                                                   client.print(Etag[PNr]);  client.print(F("$"));
                                                                   client.print(Parameter[EndSwitches+1]); client.print(F("$DATA$"));
                                                                         
                      
                                                                                                        
                                                                for (int i=StartIndex; i< EndIndex; i++)
                                                                {
                                                                   client.print(fPges[i][PNr],4);
                                                                   client.print(F("$"));
                      
                                                                   if(i%100==0) checkSerial1_for_KNX();
                                                               }
                      
                                                                client.print(F("DATA"));
                                                           }
                                                           
                                                           break;
                                                           
                                                        }
                  
                  
                                                      
                          
                                                        
                                                        //----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
                                                        default: 
                                                        {
                                                          break;
                                                        }
                                               
                                                     } //end e switch(Action)
                                             
                                            
                                                
                                        ReadText[0]=0;
                                        
                                       
                                                     
                                   }  //ENDE else if(ReadText[0]=='G' && ReadText[1]=='E' && ReadText[2]=='T') 
                                   
                                  
                         }    //end  if(client.available())
                                     
    
    
    
    
    
                                     Serial.print(F("\t\tadditional Info rxed: "));
                     
                                     int addC=0;
                                     while(client.available())
                                     {
                                        char c=client.read(); Serial.print("0x");Serial.print(c, HEX); Serial.print(" ");
                                        addC++;
                                     }
      
                                     if(addC>2) {Serial.print(" = Nr of Bytes:"); Serial.print(addC); }  else Serial.print(F(" = None"));       
    
                                     
      
    
                                             #if defined (useClientClose)
                                                
                                                   if( useClientClose_PC_Contact)
                                                   {
                                                        client.close(); Serial.print("\tclient.close done"); 
                  
                                                         byte SockNr = client.getSocketNumber(); Serial.print("  SNrP1:"); Serial.print(SockNr);  
                                                   }
                                                   
                                             #endif
    
                                             
                                                                           
                                     client.stop(); Serial.print("\tclient.stop executed");  byte SockNr = client.getSocketNumber(); Serial.print("  SkNr@End:"); Serial.print(SockNr);  
      
                                     Serial.print(F("\tdt_ms: ")); Serial.println(millis()-t1);    
                                     
                                     if(ExtraLine) Serial.println();
         
              }  //end   if(client) 
            
                 
                    
              
              
    
              
    
           
    } //End Routine
    
    
      
    
    
    
    //----------------------------------------------------------------------------------------------------------------------------
    byte AnalyseGet(char ReadText[])
    {
      
      byte bReturn=0;
    
    
      if(ReadText[3]==' ' && ReadText[4]=='/')
      {
      
           
    
            if (ReadText[5]=='f' && ReadText[6]=='a' && ReadText[7]=='v' && ReadText[8]=='i' && ReadText[9]=='c' && ReadText[10]=='o' )   bReturn=99;   //Favicon ignore  
    
            else if(ReadText[5]=='P' && ReadText[6]=='g' && ReadText[7]=='E' && ReadText[8]=='s' && ReadText[9]=='N')                     bReturn=20;   //Messwerte der letzten Zeit senden
    
            
            
      }
     
       
      return bReturn;
    }  
    
    //==============================================================================================================================================================================================================================
    
    int sendPowerToMYPV2(float DataToSend, float MaxData)
    {
    
        //This routine connects to a Server, which responds typically in 65ms and then sends ~810 bytes within 2.5ms.
    
        
                                                                                              //if(Parameter[ParameterNrDerPowerForTHOR]==0) {Serial.print(F("\n\tThor IS POWERED OFF")); return 0;}
    
                  byte OutBuffer[45];
                  
                  OutBuffer[ 0]=0x47; OutBuffer[ 1]=0x45; OutBuffer[ 2]=0x54; OutBuffer[ 3]=0x20; OutBuffer[ 4]=0x2F; OutBuffer[ 5]=0x63; OutBuffer[ 6]=0x6F; OutBuffer[ 7]=0x6E; OutBuffer[ 8]=0x74; OutBuffer[ 9]=0x72;        //GET /contr
                  OutBuffer[10]=0x6F; OutBuffer[11]=0x6C; OutBuffer[12]=0x2E; OutBuffer[13]=0x68; OutBuffer[14]=0x74; OutBuffer[15]=0x6D; OutBuffer[16]=0x6C; OutBuffer[17]=0x3F; OutBuffer[18]=0x70; OutBuffer[19]=0x6F;        //ol.html?po
                  OutBuffer[20]=0x77; OutBuffer[21]=0x65; OutBuffer[22]=0x72; OutBuffer[23]=0x3D; 
    
    
            //Ist Thor allowed, if not show this
      
                      Serial.print(F("\n\t")); Serial.print(DataToSend); Serial.print(F("->Thor"));  Serial.print(F("  Max:")); Serial.print(MaxData);   
    
                      if(PowerHeliotherm > 0 && PowerHeliotherm < 9000 && allowThorAlways==false) {Serial.print(F("  Helio ON & allowThorAlways=false -> Send 0")); MaxData=0; }
    
    
            //Thor is active, allowed to fire
      
              unsigned long Jetzt=millis();
    
              byte ThorBuffer[900];  int len=0;
    
    
                  //Ausgabewert gegen Grenzwerte checken und bei Bedarf beschränken
    
                       if(DataToSend > MaxData) DataToSend= MaxData;  
                  else if(DataToSend < min_MYPV_Power_On) DataToSend = 0; 
    
                 //korrigiert, die Wattzahl, in die von Thor benötigte, denn Thor geht von 100% = 3kW aus
                      
                      DataToSend=DataToSend/factorThor;  
                      int iData=int(DataToSend);      
    
    
            //Sicherheitsabfrage gegen negative Werte und Uhr starten,die die Zeit des letzten positiven Requesta an Thor zeigt  
                   
            if(iData > 0)  
            {
               PowerDownThorAsLongNoActivity = millis();   //compare against  + max_PowerDownThorAsLongNoActivity    denn thor schaltet nach dieser Zeit ab, wenn es keine Thor Leistung in diesem Intervall gab
    
               ThorAskedNothing=0;
    
               //Ist Thor noch aus, dann macht dieser Request keinen Sinn, aber über das Flag PowerThorUpAsThorWantsToWork wird Thor gestartet werden
               if(Parameter[ParameterNrDerPowerForTHOR]==0) { PowerThorUpAsThorWantsToWork=true; return 0;}
            }
            else
            {
              ThorAskedNothing++;
            }
             
                                  Serial.print(F("\t-> iPwr:")); Serial.print(iData); 
                                  
    
            //Zuviele Requests der Größe 0 (oder kleiner) wurden nacheinander gemacht, in diesem Fall können wir Thor einfach nicht länger ansteuern, denn dann geht dieser sowieso nach 0
            
            if(ThorAskedNothing > max_ThorAskedNothing)
            {
               ThorAskedNothing--;
    
               Serial.print(F("  > ")); Serial.print(max_ThorAskedNothing); Serial.println(F(" ZeroPWR an Thor -> stop sending until >0 again"));
               
               return 0;
            }
    
            
    
            //Jetzt haben wir einen Wert, den wir an Thor senden wollen
    
                  const byte mypv[] = {192, 168, 2, 172};  
                  
           
            
    
    
            //OUTPUT BUFFER mit Payload versehen
                
                
                                              //Started in Setup by:
                                              //         void init_Thor_OutBuffer()
                                              //         {
                                              //              OutBuffer[ 0]=0x47; OutBuffer[ 1]=0x45; OutBuffer[ 2]=0x54; OutBuffer[ 3]=0x20; OutBuffer[ 4]=0x2F; OutBuffer[ 5]=0x63; OutBuffer[ 6]=0x6F; OutBuffer[ 7]=0x6E; OutBuffer[ 8]=0x74; OutBuffer[ 9]=0x72;        //GET /contr
                                              //              OutBuffer[10]=0x6F; OutBuffer[11]=0x6C; OutBuffer[12]=0x2E; OutBuffer[13]=0x68; OutBuffer[14]=0x74; OutBuffer[15]=0x6D; OutBuffer[16]=0x6C; OutBuffer[17]=0x3F; OutBuffer[18]=0x70; OutBuffer[19]=0x6F;        //ol.html?po
                                              //              OutBuffer[20]=0x77; OutBuffer[21]=0x65; OutBuffer[22]=0x72; OutBuffer[23]=0x3D;                                                                                                                               //wer=
                                              //         }
                                              
    
                       int W=iData;         int index=28;
                       
                       if(W>=1000)
                       {
                          int T=W/1000;  byte bT=byte(T);          W=W-T*1000;
              
                          int H=W/100;   byte bH=byte(H);          W=W-H*100;
              
                          int Z=W/10;    byte bZ=byte(Z);          W=W-Z*10;
              
                          int E=W;      byte bE=byte(E);           OutBuffer[24]=bT+48;  OutBuffer[25]=bH+48;  OutBuffer[26]=bZ+48;  OutBuffer[27]=bE+48; 
                       }
              
                       else if(W>=100)
                       {
                          index=27;
              
                          int H=W/100;   byte bH=byte(H);          W=W-H*100;
              
                          int Z=W/10;    byte bZ=byte(Z);          W=W-Z*10;
              
                          int E=W;      byte bE=byte(E);           OutBuffer[24]=bH+48;  OutBuffer[25]=bZ+48;  OutBuffer[26]=bE+48;
                       }
              
                       else if(W>=10)
                       {
                          index=26;
              
                          int Z=W/10;    byte bZ=byte(Z);         W=W-Z*10;
              
                          int E=W;      byte bE=byte(E);          OutBuffer[24]=bZ+48;  OutBuffer[25]=bE+48;  
                       }
              
                       else
                       {
                         index=25;  byte bE=byte(W);              OutBuffer[24]=bE+48;    
                       }
              
                       OutBuffer[index  ]=0x20; OutBuffer[index+ 1]=0x48;  OutBuffer[index+ 2]=0x54; OutBuffer[index+3 ]=0x54; OutBuffer[index+4]=0x50; OutBuffer[index+5]=0x2F; OutBuffer[index+6]=0x31; OutBuffer[index+7]=0x2E; OutBuffer[index+8]=0x31; // blank HTTP/1.1
                       OutBuffer[index+9]=0x0D; OutBuffer[index+10]=0x0A;  OutBuffer[index+11]=0x0D; OutBuffer[index+12]=0x0A;
             
    
                                  //Serial.print("OutBuffer: ");  for(int i=0; i<index+13;i++) {Serial.print(OutBuffer[i],HEX); Serial.print(" "); } Serial.println();
    
                           
                           
    
            //Fertig nun zum Senden an Thor
             
             EthernetClient client;
    
                                   
                         Ethernet.setRetransmissionCount(1);     //<------------------------------------------------------------------------------------------------------------------- 
                         Ethernet.setRetransmissionTimeout(50);  //<------------------------------------------------------------------------------------------------------------------- 
                         
                         
                         checkSerial1_for_KNX();    //um maximale Zeit zu haben
    
    
             
              
    
                                              boolean ReturnedOK=true;
    
                                              if(client.connect(mypv, 80)==1)
                                              {
                                                                                                                                                    Serial.print(F("\tconnect OK"));
                                                                                                                                                    byte SockNr = client.getSocketNumber(); Serial.print("  SkNr@Begin:"); Serial.print(SockNr); 
    
                                                                                                                                                    
                                                        client.setConnectionTimeout(100);        //<------------------------------------------------------------------------------------------------------------------- 
                                                                                             
                                                          
                                                                                                                            
                                                               
                                                                      client.write(OutBuffer,index+13);
                                            
                                            
                                                                                      //auf Antwort warten
                                                                                      elapsedMillis wait;
                                                                                      while (len==0 && wait<500)
                                                                                      {
                                                                                         len = client.available();
                                                                                         checkSerial1_for_KNX(); 
                                                                                      }
                                            
                                            
                                                                                      //eine richtige Antwort hat ca. 807bytes
                                                                                                  
                                            
                                                                                                  if( (bDruck_sendPowerToMYPV && wait>65) || wait>75) {Serial.print("\tanswer after>65 || 75)ms: "); Serial.print(wait);  }    
                                            
                                                                                      len=client.available();       //sollten es noch mehr geworden sein
                                                                                      
                                                                                                  if(bDruck_sendPowerToMYPV && (len<800 || len>830) ) {Serial.print("\tlen(>830||<800): "); Serial.print(len);  Serial.print("\t");}
                                            
                                                                                                                                                        
                                                                                                                                                                                                                                           Serial.print("\tlen:"); Serial.print(len);
    
    
                                                                                                        //wurden zuviele oder zuwenig Bytes empfangen
                   
                    
                                                                                                        if(len<600 || len>899)     //len zeigt die Gesamtlänge der Info an, die Thor gesendet hat, diese muss über 600 sein
                                                                                                        {
                                                                                                           ErrorCounterACThor++;
                                                                                        
                                                                                                           Serial.print(F("ErrorCounterACThor ++ to ")); Serial.print(ErrorCounterACThor); Serial.print(F("\tlen:")); Serial.println(len);
    //                                                                                    
    //                                                                                                       if(len>500)    //gab es irgendeine Info jenseits 500, dann zeigen wird dies hier an
    //                                                                                                       {
    //                                                                                                          for (int i=0; i<len; i++)  {Serial.write(buffer[i]);} Serial.println();  
    //                                                                                                       }
                                                                                                           
                                                                                                           return 0; 
                                                                                                        }
                                                                                      
    
                                                                                                                                                    
                                                                             client.read(ThorBuffer,len);       //nun lesen wir empfangene Daten
                                                                            
                                                                                      
                                                                                       //Lese den Rest, wenn es etwas gibt, ohne Abspecherung
                                                                                       wait=1; int addC=0;
                                                                                       
                                                                                       while(client.available() && wait<1000)
                                                                                       {
                                                                                          char c=client.read(); if(bDruck_sendPowerToMYPV) { if(addC==0) Serial.println("\n\t\tRest1: "); Serial.print(c,HEX); Serial.print(F(" ")); }  
                                                                                          addC++;
                                                      
                                                                                          if(wait%10==0) checkSerial1_for_KNX(); 
                                                                                       }
                                                        
                                                                                       if(addC>0) {Serial.print("\t(1)readRest:"); Serial.print(addC); Serial.print(" time:"); Serial.print(wait); }
    
                                                                                      
                                                                                      wait=0; addC=0;
                                                                                      while(client.connected() && wait < 1000)
                                                                                      {
                                                                                        addC++;
                                                                                        if(wait%10==0) checkSerial1_for_KNX(); 
                                                                                      }
                                                                                      
                                                                                      if(addC>0) {Serial.print("\t(1)stillconnected:"); Serial.print(wait); }
    
    
                                                            client.close();
                                                            
                                                            client.stop(); Serial.print("\tclient.stop done");                //delibrately outside  if(client.connect(mypv, 80)==1)
    
                                                            SockNr = client.getSocketNumber(); Serial.print("  SkNr@Stop:"); Serial.print(SockNr); 
                                                                                      
    
                                                           ConnectionToThorOK=true;
                                            }
                                            else
                                            {
                                               Serial.print("\tconnect NOK");
                                               ErrorCounterACThor++;
                                               ReturnedOK=false;
    
                                               ConnectionToThorOK=false;
                                               
                                            }
    
                                          
    
    
                    if(len<360) 
                    {
                       ErrorCounterACThor++;
    
                       Serial.print(F("ErrorCounterACThor ++ to ")); Serial.print(ErrorCounterACThor); Serial.print(F("\tlen:")); Serial.println(len);
    
                       if(len>0)
                       {
                          for (int i=0; i<len; i++)  {Serial.write(ThorBuffer[i]); }  
                       }
                       
                       return 0; 
                    }
                    
    
    
    
                          //Nun sollten wir gute Daten haben, wir durchsuchen den String nach Pow=
                  
                          byte Power[5];
                    
                          for (int i=350; i<len-100; i++) 
                          {
                               //Serial.print(ThorBuffer[i]);
                          
                              if( char(ThorBuffer[i])=='P' && char(ThorBuffer[i+1])=='o' && char(ThorBuffer[i+5])=='=')
                              {
                                 Power[0]=ThorBuffer[i+6];    Power[1]=ThorBuffer[i+7]; Power[2]=ThorBuffer[i+8]; Power[3]=ThorBuffer[i+9];  Power[4]=ThorBuffer[i+10]; 
                                    
                                                                                                  
                                                                                                  //Serial.print(F("i:")); Serial.println(i);
                                 break;
                              }
                          }
    
                                                                     
                                                                   //if(bDruck_sendPowerToMYPV) {Serial.print(F("Power:")); for(int i=0; i<5; i++) Serial.print(char(Power[i])); Serial.println();}
                                                                                        
                                                            
                                                                         
    
    
    
                    
             
    
                  
    
                    //Wir analysieren, die Zahl, die Pow= folgen wird, diese kann 1 bis 4 stellig sein
                   
                    int j=0;  
                    
                    for(int i=0; i<5; i++) 
                    {
                       if( char(Power[i]) == ' ')
                       {
                         j=i;
                         break;
                       }
                    }
    
    
                              checkSerial1_for_KNX();
                          
                  
                                                                 //Serial.print(F("j:")); Serial.println(j);
                  
                    int iPower=9999;
                    
    
                            //Bilden die Zahl
                            switch (j)
                            {
                               case 1: iPower=(Power[0]-48); break;
                          
                               case 2: iPower=(Power[0]-48)*10   +  (Power[1]-48); break;
                          
                               case 3: iPower=(Power[0]-48)*100  +  (Power[1]-48)*10   +  (Power[2]-48); break;
                          
                               case 4: iPower=(Power[0]-48)*1000 +  (Power[1]-48)*100  +  (Power[2]-48)*10 + Power[3]-48; break;
                          
                               default: if(ReturnedOK==false) iPower=0; else iPower=9999; break;
                               
                            }
    
                   
                                         
    
                         if(iPower!=9999) ErrorCounterACThor=0;          //fehlerzähler zurücksetzen
                    else if(ErrorCounterACThor!=0) {Serial.println(F("\t\tErrorCounterACThor:")); Serial.println(ErrorCounterACThor);}  //ggf aufgelaufene Fehler anzeigen
    
                    
    
                   
                   //Serial Ausgabe  
    
                   if(j!=0)
                   {
                        Serial.print("\tThor retrnd: :"); Serial.print(iPower); 
    
                        if( (iPower<10 || MaxData==0)  && iData > 25  && LastThorPowerSent > 25) { Serial.print(F(" GotAZeroBackFromThor->true ")); GotAZeroBackFromThor=true; }
    
                    
                        //Mittlere Power errechnen, die Thor ausgab, seit letzeter Übermittelung an Website
         
                        powerSentToThorSinceLastContactToPC+=iPower;
                        AnzahlDerMessungen++;
        
                        Serial.print("\t\t<P(sent)>: "); Serial.print(powerSentToThorSinceLastContactToPC/AnzahlDerMessungen);
    
                   }
                   else
                   {
                        Serial.println(F("\tThor contact failed"));
                   }
    
                    unsigned long ComTimeForDefault = millis()-Jetzt;   //time_ofThorLoopControl=int(ComTimeForDefault);   //Bearbeitungszeit dieser Routine
    
                    Serial.print(F("\tdt_ms:")); Serial.println(ComTimeForDefault);
    
                    
                   
                    return iPower; 
    
    
    }
    
    //============================================================================================================================================================================================================================
    
    void checkSerial1_for_KNX()
    {
      //this routine checks 9600baud KNX Bus on Serial1
    }
    And here the code running on Mega2560

    Code:
    #include <Wire.h>
    #include <SPI.h>
    #include <Ethernet.h>
    
    byte mac[] = {0xA8, 0x61, 0x0A, 0xAE, 0x2A, 0x10};
    IPAddress ip(192, 168, 2, 185);
    IPAddress myDns(192, 168, 2, 1);
    
    EthernetClient client;
    
    IPAddress server(192,168,2,11);
    
    unsigned long lastConnectionTime = 0;           // last time you connected to the server, in milliseconds
    const unsigned long postingInterval = 5*1000;  // delay between updates, in milliseconds
    
    
    int i=1;
    
    void setup() 
    {
      
      Ethernet.init(10);  // Most Arduino shields
      Serial.begin(115200);
      
        Ethernet.begin(mac, ip, myDns);
        Serial.print("My IP address: ");
        Serial.println(Ethernet.localIP());
    
         Ethernet.setRetransmissionCount(2);     //<------------------------------------------------------------------------------------------------------------------- 
         Ethernet.setRetransmissionTimeout(50);  //<------------------------------------------------------------------------------------------------------------------- 
      
        delay(1000);
    
        
    }
    
    void loop() 
    {
     
        if (millis() - lastConnectionTime > postingInterval) 
        {
            for(int i=1; i<10; i++)
            {
              Request(i);
         
              delay(10);
            }
        }
    
    }
    
    
    
    // --------------------------------------
    
    void Request(int i)
    {
      unsigned long t1=millis();
      
      if (client.connect(server, 9010)) 
      {
         Serial.print("\nconnecting..."); Serial.print(i); 
         
         switch(i)
         {
            case 1: client.println("GET /PgEsN11"); break;
            case 2: client.println("GET /PgEsN22"); break;
            case 3: client.println("GET /PgEsN33"); break;
            case 4: client.println("GET /PgEsN44"); break;
            case 5: client.println("GET /PgEsN55"); break;
            case 6: client.println("GET /PgEsN66"); break;
            case 7: client.println("GET /PgEsN77"); break;
            case 8: client.println("GET /PgEsN88"); break;
            case 9: client.println("GET /PgEsN99"); break;
            
         }
         
         client.println();
    
         byte Wait=0; 
         while (client.available()<10 && Wait<25) {Wait++; delay(1);}
    
         Serial.print("\tWait:"); Serial.print(Wait); Serial.print("  "); Serial.print("got so far: "); Serial.print(client.available()); Serial.print("  ");
    
         if(client.available()==0)
         {
           Wait=0; 
           while (client.available()<10 && Wait<25) {Wait++; delay(1);}
           Serial.print("\textra wait:"); Serial.print(Wait); Serial.print("  "); Serial.print("after 25ms: "); Serial.print(client.available());
         }
         
         while(client.available()  ) 
         {
            char c = client.read(); Serial.write(c);
         }
    
         Serial.print("\tdt_ms:"); Serial.println(millis()-t1);
         
        
         client.stop();
    
         lastConnectionTime = millis();
      } 
      else 
      {
        Serial.println("connection #"); Serial.print(i); Serial.println(" failed");
      }
    
      
     
    }

  23. #23
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    8,605
    @Udo:
    If you could post shorter code - together with a explanation how to use it with server or client on PC side) that demostrates the bug(s) it would be good.

    However, why producing T4.1 over T4, if users cannot rely on its native Ethernet?
    You might, if you think outside the box - see that ethernet is not used as much as you think

    RAM usage: Sure, it's a 32BIT processor. An int consumes 2x the bytes. But it uses them much faster And of course it's a difference to serve the whole ethernet library compared to an external chip that uses its own memory..

  24. #24
    Member
    Join Date
    Mar 2021
    Location
    Germany
    Posts
    50
    Quote Originally Posted by Frank B View Post
    @Udo:
    If you could post shorter code - together with a explanation how to use it with server or client on PC side) that demostrates the bug(s) it would be good.


    You might, if you think outside the box - see that ethernet is not used as much as you think

    RAM usage: Sure, it's a 32BIT processor. An int consumes 2x the bytes. But it uses them much faster And of course it's a difference to serve the whole ethernet library compared to an external chip that uses its own memory..
    Hi Frank, it is very straightforward: just load code 1 on a T4.1 and code 2 (for example) on a Mega. Nothing else is necessary. The fault happens even without using any other code. The Mega creates those connection requests, the T4.1 responds to it. With the commented out part - the EthernetClient part - most of my published T4.1 code is not even used. I left it in, in case somebody wanted to add EthernetClient requests too.

    Does this answer your comment ?

    Regards RAM usage, Due is equally a 32bit device (as you know), so I am aware of issues related to it, particularly as some of my applications collect lots of parameters. I only mentioned T4.1's RAM usage because it came initially as a surprise, but has not affected me.

    In any case, my contribution here is at no means meant as criticism. It is merely a cry for help I want T4.1 to work for me

    Furthermore, just for information, I am using wired Ethernet heavily, compared to WiFi, as Arduino's u-blox WiFi capable processors (or indeed their poorly performing former Wifi shield) do not keep a reliable connection, suitable enough for real-time control, particularly if you use a wider Mesh WLAN. A fact widely mentioned on their forum but unfortunately bitterly ignored. In addition to LAN, I use Serial and RF to connect devices.

  25. #25
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    8,605
    I don't own a Mega and no shield for it, sorry.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •