#include <limits.h>

#define LCD_COLUMNS     20
char sStringBufferForLCDRow[LCD_COLUMNS + 1]; // For rendering LCD lines with sprintf()
#if defined(NO_SERIAL_INFO_PRINT)
#define JK_INFO_PRINT(...)      void();
#define JK_INFO_PRINTLN(...)    void();
#else
#define JK_INFO_PRINT(...)      Serial.print(__VA_ARGS__);
#define JK_INFO_PRINTLN(...)    Serial.println(__VA_ARGS__);
#endif

uint16_t sUint16 = 12345;
int16_t sInt16 = -21000;
struct TestStruct {
  uint16_t sUint16 = 12345;
  int16_t sInt16 = 0;
  uint32_t sUint32 = 1234557;
  long sInt32 = 0;
} sTestStruct;

void setup() {
  Serial.begin(115200);
  // Serial.begin(115200); // BUG! The 2. call disables output in Wokwi

  // put your setup code here, to run once:
  int tValue = 350;
  int tDelta = constrain(tValue, SCHAR_MIN, SCHAR_MAX);
  Serial.print(F("tValue="));
  Serial.println(tDelta);
  tValue -= tDelta;
  tDelta = constrain(tValue, SCHAR_MIN, SCHAR_MAX);
  Serial.print(F("tValue="));
  Serial.println(tDelta);
  tValue -= tDelta;
  tDelta = constrain(tValue, SCHAR_MIN, SCHAR_MAX);
  Serial.print(F("tValue="));
  Serial.println(tDelta);
  /*
     print unsigned / signed test
  */
  sInt16 -= analogRead(A1);
  sTestStruct.sInt16 -= analogRead(A2);
  sTestStruct.sInt32 -= analogRead(A2);
  JK_INFO_PRINT(F("sUint16="));
  JK_INFO_PRINTLN(sUint16);
  JK_INFO_PRINT(F("sInt16="));
  JK_INFO_PRINTLN(sInt16);

  JK_INFO_PRINT(F("sTestStruct.sUint16="));
  JK_INFO_PRINTLN(sTestStruct.sUint16);
  JK_INFO_PRINT(F("sTestStruct.sInt16="));
  JK_INFO_PRINTLN(sTestStruct.sInt16);
  JK_INFO_PRINT(F("sTestStruct.sUint32="));
  JK_INFO_PRINTLN(sTestStruct.sUint32);
  JK_INFO_PRINT(F("sTestStruct.sInt32="));
  JK_INFO_PRINTLN(sTestStruct.sInt32);

  /*
     snprintf_P ld format test
  */
  int32_t tA, tB;
  tA = -5555;
  tB = 12345678;
  snprintf_P(sStringBufferForLCDRow, LCD_COLUMNS + 1, PSTR("%6ld VA %6ld VA"), tA, tB);
  Serial.println(sStringBufferForLCDRow);
  Serial.flush();
}
uint16_t sArray1[16];
uint16_t sArray2[16];
int sLoopCounter;
void loop() {
  Serial.print(F("sLoopCounter="));
  Serial.println(sLoopCounter++);

  // MVCE for https://github.com/wokwi/avr8js/issues/136
  ADMUX = 0xC0; // select A0
  ADCSRA = ((1 << ADEN) | (1 << ADSC) | (1 << ADATE) | (1 << ADIF) | 5);
  for (unsigned int i = 0; i < 16; i++) {
    loop_until_bit_is_set(ADCSRA, ADIF);
    ADCSRA |= _BV(ADIF); // clear bit to enable recognizing next conversion has finished with "loop_until_bit_is_set(ADCSRA, ADIF)".
    uint16_t tValue = ADCL | (ADCH << 8);
    sArray1[i] = tValue; // store value at current counter index
  }
  ADCSRA = ((1 << ADEN) | (1 << ADIF) | 5); // Disable auto-triggering (free running mode), but the last conversion is still running
  delay(1);
  ADMUX = 0xC1;// select A1
  ADCSRA = ((1 << ADEN) | (1 << ADSC) | (1 << ADATE) | (1 << ADIF) | 5);
  for (unsigned int i = 0; i < 16; i++) {
    loop_until_bit_is_set(ADCSRA, ADIF);
    ADCSRA |= _BV(ADIF); // clear bit to enable recognizing next conversion has finished with "loop_until_bit_is_set(ADCSRA, ADIF)".
    uint16_t tValue = ADCL | (ADCH << 8);
    sArray2[i] = tValue; // store value at current counter index
  }
  ADCSRA = ((1 << ADEN) | (1 << ADIF) | 5); // Disable auto-triggering (free running mode), but the last conversion is still running

  Serial.println(F("Print i=<ValueA0>|<ValueA1>"));#
  /*
   * But we see i=<ValueA1>|<ValueA0> 
   * and after 12 to 13 samples i=<ValueA0>|<ValueA0> or i=<ValueA1>|<ValueA1>
  */
  for (unsigned int i = 0; i < 16; i++) {
    Serial.print(i);
    Serial.print('=');
    Serial.print(sArray1[i]);
    Serial.print('|');
    Serial.print(sArray2[i]);
    Serial.print(F(", "));
  }
  Serial.println();

  delay(2000);
}

A0
A1