ROBIN2: Planning and Implementing an Arduino Program
Two things I do:
1) Print every function. Anything that takes more than one page is too long.
2) Use lots of functions. Every function should have a name that clearly describes what it does, and should do only one thing. processData() is a lousy name. So is printTimeAndReadTemperaturesAndMakeGETRequest().
By using lots of functions, each one can be quite small. Small functions are easy to test. Once a function is KNOWN to work, with all input data, it can then be treated as an infallible black box.
Look at Robin2's serial input tutorial. The recvWithStartEndMarkers() conceptually looks quite complicated, but a little study shows that it really is quite simple. A few tests will show that recvWithStartEndMarkers() just works. So, if you have a program that reads serial data, and does so by calling recvWithStartEndMarkers(), then it is quite safe to assume that any problems with the program are NOT caused by recvWithStartEndMarkers().