// By Koepel
//
// Test with Raspberry Pi Pico + Arduino + Mbed + Schedular
// This is the default "arduino-core" instead of "arduino-community"
// That can be selected in the diagram.json, see the docs:
//   https://docs.wokwi.com/parts/wokwi-pi-pico
//
// See also my project with a LCD and a Pico in "arduino-community" mode:
//   https://wokwi.com/arduino/projects/317086316856607298
//
// Update 1 July 2023:
//   The pins for the I2C bus have changed, now 4 and 5.
//
// Note: A Raspberry Pi Pico is a 3.3V board and most LCD displays are 5V.
//

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Scheduler.h>

using namespace mbed;
using namespace rtos;

LiquidCrystal_I2C lcd( 0x27, 20, 4);

Mutex lcd_mutex;                          // mutex for the (hardware resource) LCD

void setup() 
{
  Serial.begin(115200);
  while (!Serial);   // wait for the SerialUSB port to connect
  Serial.println( "The sketch has started");
 
  Serial.print( "PIN_WIRE_SDA = ");
  Serial.print( PIN_WIRE_SDA);            // defined in pins_arduino.h
  Serial.print( ", PIN_WIRE_SCL = ");
  Serial.println( PIN_WIRE_SCL);

  pinMode( LED_BUILTIN, OUTPUT);

  // Start the I2C bus
  Wire.begin();
  Wire.setClock( 400000);                // 400kHz clock for I2C bus

  // Initialize the display
  lcd.init();
  lcd.backlight();


  // Show some startup messages
  //
  //    01234567890123456789
  //   +--------------------
  // 0 | Raspberry Pi Pico
  // 1 | =================
  // 2 |<shifting text>
  // 3 |<counter>

  lcd.setCursor( 1, 0);
  lcd.print( "Raspberry Pi Pico");

  lcd.setCursor( 1, 1);
  lcd.print( "=================");


  // The Arduino loop() is one task, add more tasks
  // Each task gets 1024 bytes stack by default.
  Scheduler.startLoop( blinkLoop);
  Scheduler.startLoop( textLoop);
}


// --------------------------------------------------
// TASK 1      show the millis value on the display
// --------------------------------------------------
void loop() 
{
  lcd_mutex.lock();             // two tasks on a single display requires mutex
  lcd.setCursor( 0, 3);
  lcd.print( millis());
  lcd_mutex.unlock();
  delay( 250);
}


// --------------------------------------------------
// TASK 2      blink the (very tiny) onboard led
// --------------------------------------------------
void blinkLoop()
{
  // It is a very small green led, hard to see.
  digitalWrite( LED_BUILTIN, HIGH);
  delay( 200);
  digitalWrite( LED_BUILTIN, LOW);
  delay( 300);
}


// --------------------------------------------------
// TASK 3      roll text to left and right
// --------------------------------------------------
const char myText[] = "   Raspberry Pi Pico + Arduino + Mbed + Wokwi + Schedular + rtos   ";
int textIndex = 0;        // 0 is first character to start with
int direction = 1;        // +1 for right shift, -1 for left shift
const int maxIndex = strlen( myText) - 20;

void textLoop()
{
  textIndex += direction;
  if( textIndex == 0 || textIndex == maxIndex)
    direction = -direction;

  lcd_mutex.lock();        // two tasks on a single display requires mutex
  // always print 20 characters
  for( int i=0; i<20; i++)
  {
    lcd.setCursor( i, 2);
    lcd.print( myText[textIndex + i]);
  }
  lcd_mutex.unlock();

  delay( 80);
}
BOOTSELLED1239USBRaspberryPiPico©2020RP2-8020/21P64M15.00TTT