{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "60b1df67-aa55-4b3f-b9ff-41716ea8eb11",
   "metadata": {},
   "source": [
    "## Install the MicroPython kernel\n",
    "To run MicroPython code, you'll need to install the `MicroPython - USB` kernel. Follow these steps:\n",
    "\n",
    "1. Visit this GitHub page https://github.com/goatchurchprime/jupyter_micropython_kernel\n",
    "2. Install the kernel into Jupyter.\n",
    "4. After installation, select the kernel `MicroPython - USB` to run MicroPython code.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3e1eaac9-5bf1-495f-8464-59e15aed589d",
   "metadata": {},
   "source": [
    "## Customizing the run button\n",
    "\n",
    "By default, the option for the `run` button is set to `Run Selected Cell and Advance`. However, for certain use cases, this default behavior might be confusing, beacause after cell execution, the cursor automatically jumps to next cell. To modify it to `Run Selected Cell and Do not Advance`, follow these steps:\n",
    "\n",
    "1. Navigate to the Jupyter file browser.\n",
    "2. Click on `Settings` in the top menu, then select `Settings Editor`.\n",
    "3. In the left menu, choose `Notebook Panel`.\n",
    "4. Locate the section with the `unique name`: `run` (it's `toolbar-5` by default).\n",
    "5. Change the `Command id` from `notebook:run-cell-and-select-next` to `notebook:run-cell`.\n",
    "6. Additionally, set the `Item icon id` to `ui-components:run`.\n",
    "7. Refresh the active notebook.\n",
    "\n",
    "To revert to the default option, simply click on `Restore to Defaults`."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bb0b9359-5de5-468f-82b2-fea3e99928de",
   "metadata": {},
   "source": [
    "## Flashing new firmware\n",
    "\n",
    "Flash new firmware via esptool. Esptool must be located in the same folder as this notebook."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "de5bb819-cfea-4fe7-9bfb-36019c02df8b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[34mExecuting:\n",
      "  esptool --port COM6 erase_flash\n",
      "\n",
      "\u001b[0mesptool.py v4.7.0\n",
      "Serial port COM6\n",
      "Connecting....\n",
      "\u001b[34m[Press the PRG button now if required]\n",
      "\u001b[0mDetecting chip type... Unsupported detection protocol, switching and trying again...\n",
      "Connecting....\n",
      "\u001b[34m[Press the PRG button now if required]\n",
      "\u001b[0mDetecting chip type... ESP32\n",
      "Chip is ESP32-D0WD-V3 (revision v3.1)\n",
      "Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None\n",
      "Crystal is 40MHz\n",
      "MAC: 6c:c8:40:8b:d2:b4\n",
      "Uploading stub...\n",
      "Running stub...\n",
      "Stub running...\n",
      "Erasing flash (this may take a while)...\n",
      "Chip erase completed successfully in 5.7s\n",
      "Hard resetting via RTS pin...\n",
      "\u001b[34mExecuting:\n",
      "  esptool --port COM6 --chip esp32 write_flash -z 0x1000 firmware/ESP32_GENERIC-20240222-v1.22.2.bin\n",
      "\n",
      "\u001b[0mesptool.py v4.7.0\n",
      "Serial port COM6\n",
      "Connecting.....\n",
      "\u001b[34m[Press the PRG button now if required]\n",
      "\u001b[0mChip is ESP32-D0WD-V3 (revision v3.1)\n",
      "Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None\n",
      "Crystal is 40MHz\n",
      "MAC: 6c:c8:40:8b:d2:b4\n",
      "Uploading stub...\n",
      "Running stub...\n",
      "Stub running...\n",
      "Configuring flash size...\n",
      "Flash will be erased from 0x00001000 to 0x001a9fff...\n",
      "Compressed 1737776 bytes to 1143554...\n",
      "Writing at 0x00001000... (1 %)\n",
      "Writing at 0x00010a97... (2 %)\n",
      "Writing at 0x00018bb4... (4 %)\n",
      "Writing at 0x00020d44... (5 %)\n",
      "Writing at 0x0002704e... (7 %)\n",
      "Writing at 0x00030666... (8 %)\n",
      "Writing at 0x0003f150... (10 %)\n",
      "Writing at 0x000457df... (11 %)\n",
      "Writing at 0x0004ebd0... (12 %)\n",
      "Writing at 0x00054cbb... (14 %)\n",
      "Writing at 0x0005a183... (15 %)\n",
      "Writing at 0x0005f27a... (17 %)\n",
      "Writing at 0x00064362... (18 %)\n",
      "Writing at 0x00069359... (20 %)\n",
      "Writing at 0x0006e3e6... (21 %)\n",
      "Writing at 0x000735fa... (22 %)\n",
      "Writing at 0x00078141... (24 %)\n",
      "Writing at 0x0007ce65... (25 %)\n",
      "Writing at 0x0008388f... (27 %)\n",
      "Writing at 0x00088e6c... (28 %)\n",
      "Writing at 0x0008e944... (30 %)\n",
      "Writing at 0x00093fe2... (31 %)\n",
      "Writing at 0x00099661... (32 %)\n",
      "Writing at 0x0009f242... (34 %)\n",
      "Writing at 0x000a475e... (35 %)\n",
      "Writing at 0x000a9d37... (37 %)\n",
      "Writing at 0x000afd14... (38 %)\n",
      "Writing at 0x000b5c05... (40 %)\n",
      "Writing at 0x000bbca5... (41 %)\n",
      "Writing at 0x000c1690... (42 %)\n",
      "Writing at 0x000c673c... (44 %)\n",
      "Writing at 0x000cc318... (45 %)\n",
      "Writing at 0x000d2122... (47 %)\n",
      "Writing at 0x000d7cde... (48 %)\n",
      "Writing at 0x000ddcba... (50 %)\n",
      "Writing at 0x000e2c48... (51 %)\n",
      "Writing at 0x000e7ca9... (52 %)\n",
      "Writing at 0x000ecd89... (54 %)\n",
      "Writing at 0x000f21f3... (55 %)\n",
      "Writing at 0x000f7697... (57 %)\n",
      "Writing at 0x000fcc38... (58 %)\n",
      "Writing at 0x00101da3... (60 %)\n",
      "Writing at 0x00106e43... (61 %)\n",
      "Writing at 0x0010cf4b... (62 %)\n",
      "Writing at 0x001131da... (64 %)\n",
      "Writing at 0x001180c3... (65 %)\n",
      "Writing at 0x0011d470... (67 %)\n",
      "Writing at 0x00122af8... (68 %)\n",
      "Writing at 0x00127dcc... (70 %)\n",
      "Writing at 0x0012ce81... (71 %)\n",
      "Writing at 0x00132be7... (72 %)\n",
      "Writing at 0x00137d8c... (74 %)\n",
      "Writing at 0x0013d1ef... (75 %)\n",
      "Writing at 0x00142463... (77 %)\n",
      "Writing at 0x00147b68... (78 %)\n",
      "Writing at 0x0014d140... (80 %)\n",
      "Writing at 0x001527fb... (81 %)\n",
      "Writing at 0x00158325... (82 %)\n",
      "Writing at 0x0015de70... (84 %)\n",
      "Writing at 0x001638b7... (85 %)\n",
      "Writing at 0x0016b541... (87 %)\n",
      "Writing at 0x00173097... (88 %)\n",
      "Writing at 0x0017aa80... (90 %)\n",
      "Writing at 0x0017feef... (91 %)\n",
      "Writing at 0x001859e5... (92 %)\n",
      "Writing at 0x0018e0ce... (94 %)\n",
      "Writing at 0x00193b9f... (95 %)\n",
      "Writing at 0x001995e1... (97 %)\n",
      "Writing at 0x0019ee6a... (98 %)\n",
      "Writing at 0x001a4812... (100 %)\n",
      "Wrote 1737776 bytes (1143554 compressed) at 0x00001000 in 101.3 seconds (effective 137.2 kbit/s)...\n",
      "Hash of data verified.\n",
      "\n",
      "Leaving...\n",
      "Hard resetting via RTS pin...\n"
     ]
    }
   ],
   "source": [
    "%esptool erase\n",
    "%esptool esp32 firmware/ESP32_GENERIC-20240222-v1.22.2.bin"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d47bbc46-d358-47fa-8192-d0a29dbf95e0",
   "metadata": {},
   "source": [
    "## Connect to device\n",
    "\n",
    "Connect to device via USB serial interface. Port is autodetected. Required command before program start."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a38e2a25-be18-4b8b-b403-32ca27733071",
   "metadata": {},
   "outputs": [],
   "source": [
    "%serialconnect"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0283278c-5063-4008-bb2f-e7fb890e8291",
   "metadata": {},
   "source": [
    "## Load custom module to device"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b8e742c4-e10e-4fad-ae4a-32d2af2df95f",
   "metadata": {},
   "outputs": [],
   "source": [
    "%sendtofile RGBLed.py\n",
    "\n",
    "# internal library\n",
    "from machine import Pin, PWM\n",
    "\n",
    "#intensities\n",
    "SUPER_BRIGHT   = const(1023)\n",
    "BRIGHT         = const(511)\n",
    "MEDIUM         = const(255)\n",
    "DIM            = const(127)\n",
    "SUPER_DIM      = const(63)\n",
    "NEARLY_VISIBLE = const(7) \n",
    "OFF            = const(0) \n",
    "\n",
    "# base colors\n",
    "RED     = (1,    0,    0)\n",
    "GREEN   = (0,    1,    0)\n",
    "BLUE    = (0,    0,    1)\n",
    "\n",
    "BLACK   = (0,    0,    0)\n",
    "WHITE   = (1,    1,    1)\n",
    "\n",
    "CYAN    = (0,    1,    1)\n",
    "MAGENTA = (1,    0,    1) \n",
    "YELLOW  = (1,    1,    0)\n",
    "\n",
    "# operating class\n",
    "class RGBLed:\n",
    "    def __init__(self, pinRed, pinGreen, pinBlue, freq):\n",
    "        # create pwm pins\n",
    "        self.__pwmR = PWM(pinRed)\n",
    "        self.__pwmG = PWM(pinGreen)\n",
    "        self.__pwmB = PWM(pinBlue)\n",
    "\n",
    "        # set frequency\n",
    "        self.__pwmR.freq(freq)\n",
    "        self.__pwmG.freq(freq)\n",
    "        self.__pwmB.freq(freq)\n",
    "\n",
    "    def light(self, color, intensity=1023):\n",
    "        self.__pwmR.duty(int(intensity * color[0]))\n",
    "        self.__pwmG.duty(int(intensity * color[1]))\n",
    "        self.__pwmB.duty(int(intensity * color[2]))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2d47509a-532e-4da1-b1d8-8f46c487d0ea",
   "metadata": {},
   "source": [
    "## Simple program using custom module"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f6518ae4-05e8-4e5b-8837-a574d8a616b2",
   "metadata": {},
   "outputs": [],
   "source": [
    "from RGBLed import *\n",
    "\n",
    "ledRGB = RGBLed(Pin(25), Pin(26), Pin(27), 10000)\n",
    "\n",
    "ledRGB.light(CYAN)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e680daab-1c60-4571-bf3b-e859dc7b9731",
   "metadata": {},
   "source": [
    "## Show device filesystem"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "14997298-27bb-4e3b-91ce-d8b620e3c78d",
   "metadata": {},
   "outputs": [],
   "source": [
    "%ls "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "962d3ee8-63e2-4007-be03-ad3af27d750e",
   "metadata": {},
   "source": [
    "## Show contents of stored file"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "160c3261-49fd-4eed-9d61-5d3c63f418aa",
   "metadata": {},
   "outputs": [],
   "source": [
    "%fetchfile --print boot.py"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a959657f-b4a0-4231-bf6e-132e13cd9dd4",
   "metadata": {},
   "source": [
    "## Store terminal output into file (PC filesystem)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "66e4e37d-033c-4a3e-b018-98d439859dc0",
   "metadata": {},
   "outputs": [],
   "source": [
    "%capture output.txt\n",
    "\n",
    "# program to generate output text\n",
    "for i in range(0, 10):\n",
    "    print(i)\n",
    "    i += 1"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "348504d8-0fac-4a8f-bc86-30b861149c0c",
   "metadata": {},
   "source": [
    "## Load program to boot file\n",
    "\n",
    "After completion, reset device usnig EN button. The serial connection will be lost, so you need to reconnect using %serialconnect command."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "aad4a8c0-1b5d-4b94-95e5-dbc546ba826c",
   "metadata": {},
   "outputs": [],
   "source": [
    "%sendtofile boot.py\n",
    "\n",
    "from RGBLed import *\n",
    "import time\n",
    "\n",
    "ledRGB = RGBLed(Pin(25), Pin(26), Pin(27), 10000)\n",
    "\n",
    "while True:\n",
    "    ledRGB.light(RED)\n",
    "    time.sleep(1)\n",
    "    ledRGB.light(MAGENTA)\n",
    "    time.sleep(1)\n",
    "    ledRGB.light(YELLOW)\n",
    "    time.sleep(1)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "29df8fc3-d866-4434-8505-af90c24735b0",
   "metadata": {},
   "source": [
    "## Show all \"Magic commands\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ac8d25b0-f7ef-4a72-91c1-a2939ea78041",
   "metadata": {},
   "outputs": [],
   "source": [
    "%lsmagic"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "MicroPython - USB",
   "language": "micropython",
   "name": "micropython"
  },
  "language_info": {
   "codemirror_mode": "python",
   "file_extension": ".py",
   "mimetype": "text/python",
   "name": "micropython"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
