<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tutorials &#8211; PICSimLab</title>
	<atom:link href="https://picsimlab.com/tutorials/feed/" rel="self" type="application/rss+xml" />
	<link>https://picsimlab.com</link>
	<description>The Ultimate Open Source Simulator for PIC, Arduino &#38; ESP32.</description>
	<lastBuildDate>Thu, 22 Oct 2026 04:19:52 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.3</generator>

<image>
	<url>https://picsimlab.com/wp-content/uploads/2026/05/favicon-150x150.png</url>
	<title>Tutorials &#8211; PICSimLab</title>
	<link>https://picsimlab.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>AVR, STM32 and ESP32 in PICSimLab: VSCode + PlatformIO, and the Arduino IDE</title>
		<link>https://picsimlab.com/arduino-ide-picsimlab-workflow/</link>
		
		<dc:creator><![CDATA[Admin]]></dc:creator>
		<pubDate>Thu, 22 Oct 2026 04:19:52 +0000</pubDate>
				<category><![CDATA[Tutorials]]></category>
		<guid isPermaLink="false">https://picsimlab.com/arduino-ide-picsimlab-workflow/</guid>

					<description><![CDATA[AVR, STM32 and ESP32 in PICSimLab: VSCode + PlatformIO, and the Arduino IDE For non-PIC boards, PICSimLab documentation names two distinct integration paths, and they are often confused. Keep them separate: The Code Project Wizard path is VSCode + PlatformIO. For boards based on AVR, STM32 and ESP32, the wizard generates projects that use VSCode...]]></description>
										<content:encoded><![CDATA[<h1>AVR, STM32 and ESP32 in PICSimLab: VSCode + PlatformIO, and the Arduino IDE</h1>
<p>For non-PIC boards, PICSimLab documentation names two distinct integration paths, and they are often confused. Keep them separate:</p>
<ul>
<li><strong>The Code Project Wizard path is VSCode + PlatformIO.</strong> For boards based on <strong>AVR, STM32 and ESP32</strong>, the wizard generates projects that use <strong>VSCode with PlatformIO</strong> — not Arduino IDE projects.</li>
<li><strong>The Arduino IDE path is an integration, not the wizard.</strong> PICSimLab integrates with the Arduino IDE for programming — the simavr (AVR) board examples use the Arduino IDE with avr-gcc, and ESP32 firmware can be flashed from the Arduino IDE (or IDF) tooling via esptool.py over the serial link.</li>
</ul>
<p>PICSimLab itself still edits no source code on either path; editing and compiling happen in VSCode/PlatformIO or in the Arduino IDE, exactly as with a real board.</p>
<h2>Path A: VSCode + PlatformIO (the wizard path)</h2>
<ol>
<li><strong>Install the prerequisite first:</strong> the official requirements state that ESP32, STM32, Atmel (AVR) and STM8/C51 boards need <strong>PlatformIO IDE for VSCode</strong> installed before you use the wizard.</li>
<li><strong>Select the board and chip</strong> in PICSimLab — for example Arduino Uno (ATmega328P), Blue Pill (STM32F103C8T6) or ESP32-DevKitC.</li>
<li><strong>Generate the project</strong> with the Code Project Wizard. The official template list covers these boards under PlatformIO with the <strong>Arduino framework</strong> (Arduino Mega/Nano/Uno, Blue Pill, STM32 H103, ESP32, ESP32-C3, Franzininho DIY, uCboard/STM8S103), plus <strong>CMSIS</strong> templates for the two STM32 boards and <strong>IDF</strong> templates for the ESP32 boards.</li>
<li><strong>Build and load:</strong> build in VSCode, then load the resulting firmware into PICSimLab — the <code>picsimlab_tool</code> command-line helper (documented form: <code>picsimlab_tool file [.hex or .bin]</code>) exists precisely to upload firmware and integrates with PlatformIO. Board and chip must match the build, as the <a href="https://picsimlab.com/load-hex-file-picsimlab/">hex loading guide</a> explains.</li>
<li><strong>Debug (desktop only):</strong> each QEMU/simavr backend has a GDB path — avr-gdb for AVR, arm-gdb for STM32, esp32-gdb for ESP32 — and PlatformIO can be configured with <code>debug_tool = custom</code> for graphical debugging. Connection failures are covered in <a href="https://picsimlab.com/picsimlab-gdb-debug-connection/">GDB connection fixes</a>.</li>
</ol>
<h2>Path B: The Arduino IDE integration</h2>
<p>If your code already lives in the Arduino IDE, you do not have to move it to PlatformIO to use PICSimLab:</p>
<ul>
<li><strong>AVR / simavr boards:</strong> the official documentation&#8217;s serial chapter has a dedicated <em>Arduino IDE Integration (simavr)</em> section, and the simavr board example sources are used with the Arduino IDE + avr-gcc. Compile the sketch for the matching board chip (ATmega328P for Uno/Nano, ATmega2560 for Mega) and load the produced firmware — see the board notes in <a href="https://picsimlab.com/arduino-uno-nano-picsimlab/">Arduino Uno and Nano in PICSimLab</a>.</li>
<li><strong>ESP32:</strong> the QEMU ESP32 documentation states you can use the Arduino IDE or IDF <code>esptool.py</code> to flash PICSimLab&#8217;s ESP32-DevKitC as if it were a real ESP32 board, following the serial-port setup. One hard rule from the same page: <strong>QEMU ESP32 does not support the QIO and QOUT flash modes — use only DIO or DOUT</strong>. Flash failures are covered in <a href="https://picsimlab.com/picsimlab-esp32-flash-mode-qemu/">ESP32 flash mode fixes</a> and board context in <a href="https://picsimlab.com/esp32-devkitc-picsimlab/">ESP32-DevKitC in PICSimLab</a>.</li>
<li><strong>Serial prerequisite:</strong> both flashing and serial sketches rely on the desktop serial setup — a virtual null-modem pair (com0com on Windows, tty0tty on Linux) at 8N1. Setup is in <a href="https://picsimlab.com/virtual-serial-ports-picsimlab/">virtual serial ports for PICSimLab</a>. The <a href="https://picsimlab.com/online/">online version</a> cannot do this: it has no serial communication beyond the IO Vterm terminal.</li>
</ul>
<h2>Which path should you pick?</h2>
<p>New project on an AVR, STM32 or ESP32 board: use Path A — it is the wizard&#8217;s documented route, the templates are maintained for it, and debugging hooks are described for it. Existing Arduino IDE sketch you do not want to port: use Path B, accepting that it is an integration for programming/flashing rather than the project-generation path. PIC chips are a third, separate route entirely: <a href="https://picsimlab.com/mplab-x-xc8-picsimlab-workflow/">MPLAB X + XC8</a>. All three meet on the <a href="https://picsimlab.com/getting-started/">getting started path</a> once your first simulation runs.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>The PIC Workflow: MPLAB X + XC8 Projects for PICSimLab</title>
		<link>https://picsimlab.com/mplab-x-xc8-picsimlab-workflow/</link>
		
		<dc:creator><![CDATA[Admin]]></dc:creator>
		<pubDate>Thu, 22 Oct 2026 04:19:42 +0000</pubDate>
				<category><![CDATA[Tutorials]]></category>
		<guid isPermaLink="false">https://picsimlab.com/mplab-x-xc8-picsimlab-workflow/</guid>

					<description><![CDATA[The PIC Workflow: MPLAB X + XC8 Projects for PICSimLab PICSimLab has no source-code editor — by design, it emulates hardware, and you write code with the same tools you would use for a real board. For PIC microcontrollers that tool chain is MPLAB X IDE with the XC8 compiler, and PICSimLab&#8217;s Code Project Wizard...]]></description>
										<content:encoded><![CDATA[<h1>The PIC Workflow: MPLAB X + XC8 Projects for PICSimLab</h1>
<p>PICSimLab has no source-code editor — by design, it emulates hardware, and you write code with the same tools you would use for a real board. For PIC microcontrollers that tool chain is <strong>MPLAB X IDE with the XC8 compiler</strong>, and PICSimLab&#8217;s Code Project Wizard is built around it: <strong>for boards based on PIC16F and PIC18F microcontrollers, the wizard generates projects that use MPLAB X</strong>. This guide walks the whole path from wizard to a debuggable simulation.</p>
<h2>Prerequisite: install MPLAB X and XC8 first</h2>
<p>The wizard&#8217;s PIC path assumes its tools already exist. Per the official software requirements, boards based on <strong>PIC16F and PIC18F need MPLAB X IDE and the XC8 compiler installed beforehand</strong>. Install both from Microchip before you generate a project; without XC8, the generated project opens but cannot build. (The AVR, STM32 and ESP32 boards use a different wizard path — VSCode + PlatformIO — covered in the <a href="https://picsimlab.com/arduino-ide-picsimlab-workflow/">PlatformIO / Arduino IDE workflow</a>.)</p>
<h2>Step 1: Select the board and chip in PICSimLab</h2>
<p>Select your board and microcontroller first — for example McLab2 with a PIC16F877A, or the same board with a PIC18F4550. The wizard generates the project for the current selection, so changing the chip afterwards means regenerating. Board pages on this site list exactly which chips each board supports: see <a href="https://picsimlab.com/mclab2-board-picsimlab/">McLab2</a> and <a href="https://picsimlab.com/picgenios-board-picsimlab/">PICGenios</a>.</p>
<h2>Step 2: Generate the project with the Code Project Wizard</h2>
<p>Run the Code Project Wizard for the selected board. For PIC16F/PIC18F boards it creates an <strong>MPLAB X project</strong> using XC8, with the official code templates as the starting point — the template list includes Blink examples (including a Blink FreeRTOS template) for the PIC boards. Save the generated project in your own working folder.</p>
<h2>Step 3: Write code and build in MPLAB X</h2>
<p>Edit the code in MPLAB X, not in PICSimLab. Two habits save debugging time later:</p>
<ul>
<li>Set the clock define your code relies on (for example <code>_XTAL_FREQ</code> in XC8 delay calls) to the clock configured for the board in PICSimLab.</li>
<li>Build until the project compiles cleanly. A successful build produces the <code>.hex</code> file you will load — if the build fails, fix it here; PICSimLab can only run firmware that actually built.</li>
</ul>
<h2>Step 4: Load the .hex and run</h2>
<p>Back in PICSimLab, with the same board and chip selected, load the built <code>.hex</code> and run. The full loading order and the mismatch checks are in the <a href="https://picsimlab.com/load-hex-file-picsimlab/">hex loading guide</a>; the <a href="https://picsimlab.com/pic16f877a-blink-led-picsimlab/">PIC16F877A blink tutorial</a> and the <a href="https://picsimlab.com/pic18f4550-picsimlab-first-project/">PIC18F4550 first project</a> show this exact workflow with complete example code.</p>
<h2>Step 5 (optional): Debug from MPLAB X</h2>
<p>The desktop version can be debugged from inside MPLAB X, the way you would debug a real board: install the PICSimLab plugin file <code>com-picsim-picsimlab.nbm</code> in MPLAB X, and MPLAB X connects to PICSimLab through a TCP socket on <strong>port 1234</strong> (allow it through your firewall). The complete setup is in the <a href="https://picsimlab.com/mplab-x-picsimlab-plugin/">MPLAB X plugin guide</a>; if the connection fails, work through <a href="https://picsimlab.com/picsimlab-mplab-x-plugin-connection/">plugin connection fixes</a>. Note this is a desktop-only feature — the <a href="https://picsimlab.com/online/">online version</a> has no debugging support.</p>
<p>Where does this fit in the bigger picture? This workflow is Step 4 material on the <a href="https://picsimlab.com/getting-started/">getting started path</a>: install, first simulation, board choice, then your own compiled projects.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to Load a .hex or .bin File into PICSimLab</title>
		<link>https://picsimlab.com/load-hex-file-picsimlab/</link>
		
		<dc:creator><![CDATA[Admin]]></dc:creator>
		<pubDate>Thu, 22 Oct 2026 04:19:32 +0000</pubDate>
				<category><![CDATA[Tutorials]]></category>
		<guid isPermaLink="false">https://picsimlab.com/load-hex-file-picsimlab/</guid>

					<description><![CDATA[How to Load a .hex or .bin File into PICSimLab PICSimLab does not run source code. It runs compiled firmware — the .hex file (or, on some paths, a .bin file) that your compiler produced. Loading sounds trivial, and it is, provided one rule is respected: the board and microcontroller selected in PICSimLab must match...]]></description>
										<content:encoded><![CDATA[<h1>How to Load a .hex or .bin File into PICSimLab</h1>
<p>PICSimLab does not run source code. It runs <strong>compiled firmware</strong> — the <code>.hex</code> file (or, on some paths, a <code>.bin</code> file) that your compiler produced. Loading sounds trivial, and it is, provided one rule is respected: <strong>the board and microcontroller selected in PICSimLab must match the chip the firmware was built for</strong>. Most &ldquo;it loads but does nothing&rdquo; reports trace back to that single mismatch.</p>
<h2>Where the file comes from</h2>
<ul>
<li><strong>PIC (PIC16F / PIC18F):</strong> build the project in MPLAB X with the XC8 compiler; the build output folder contains the <code>.hex</code>. See the <a href="https://picsimlab.com/mplab-x-xc8-picsimlab-workflow/">MPLAB X + XC8 workflow</a>.</li>
<li><strong>AVR, STM32, ESP32:</strong> the Code Project Wizard generates VSCode + PlatformIO projects for these boards; PlatformIO builds produce the firmware file to load. The command-line helper <code>picsimlab_tool</code> can also upload a file directly — its documented form is <code>picsimlab_tool file [.hex or .bin]</code> — and it integrates with PlatformIO. See the <a href="https://picsimlab.com/arduino-ide-picsimlab-workflow/">PlatformIO / Arduino IDE workflow</a>.</li>
<li><strong>Online version:</strong> files are loaded by drag and drop or the Load button in the browser, as <code>.hex</code>, <code>.pzw</code> (workspace) or <code>.pcf</code> (spare-parts configuration). See <a href="https://picsimlab.com/online/">PICSimLab Online</a>.</li>
</ul>
<h2>The loading order that works</h2>
<ol>
<li><strong>Select the board first.</strong> Pick the board your project targets (for example McLab2 for a PIC16F877A project).</li>
<li><strong>Select the exact microcontroller.</strong> Set the chip to the one the firmware was compiled for — PIC16F877A firmware on a PIC18F4550 selection is a mismatch even though both sit on the same board list.</li>
<li><strong>Load the file.</strong> Use the load/open control to point PICSimLab at the freshly built <code>.hex</code> (or <code>.bin</code> where that is the build output). If you rebuilt after a code change, reload — the simulator keeps running the old file until you do.</li>
<li><strong>Run.</strong> Start the simulation and check for the expected behaviour: an LED state change, output on a spare part, characters in the terminal.</li>
</ol>
<h2>Three checks before you blame the simulator</h2>
<ul>
<li><strong>Did the build actually succeed?</strong> A failed compile can leave a stale <code>.hex</code> from an earlier, different project in the output folder. Rebuild cleanly and confirm the file&#8217;s timestamp is new.</li>
<li><strong>Is the clock consistent?</strong> If your code uses delays based on a clock define such as <code>_XTAL_FREQ</code>, it must match the clock configured for the board in PICSimLab, or everything runs at the wrong speed.</li>
<li><strong>Are you loading the right file type?</strong> A <code>.pzw</code> is a saved workspace and a <code>.pcf</code> is a spare-parts configuration — neither is firmware. The firmware itself is the <code>.hex</code> / <code>.bin</code>.</li>
</ul>
<p>Still stuck — the file will not load, or loads with no visible effect? Work through the dedicated troubleshooting guide: <a href="https://picsimlab.com/picsimlab-hex-file-not-loading/">PICSimLab hex file not loading</a>. If the file loads and the board is selected correctly but the simulation itself will not run, see <a href="https://picsimlab.com/picsimlab-simulation-not-running/">simulation not running</a> instead. And if you have not run anything yet, start with the <a href="https://picsimlab.com/picsimlab-first-simulation/">first simulation walkthrough</a>, which uses a built-in example so the firmware side is known-good.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Your First Simulation in PICSimLab</title>
		<link>https://picsimlab.com/picsimlab-first-simulation/</link>
		
		<dc:creator><![CDATA[Admin]]></dc:creator>
		<pubDate>Thu, 22 Oct 2026 04:19:21 +0000</pubDate>
				<category><![CDATA[Tutorials]]></category>
		<guid isPermaLink="false">https://picsimlab.com/picsimlab-first-simulation/</guid>

					<description><![CDATA[Your First Simulation in PICSimLab: From Install to a Blinking LED This walkthrough takes you from a fresh install to a running simulation with a visible result: an LED switching on and off. It uses the best-documented combination in PICSimLab — a PIC16F877A on the McLab2 board — and the built-in example route, so you...]]></description>
										<content:encoded><![CDATA[<h1>Your First Simulation in PICSimLab: From Install to a Blinking LED</h1>
<p>This walkthrough takes you from a fresh install to a running simulation with a visible result: an LED switching on and off. It uses the best-documented combination in PICSimLab — a <strong>PIC16F877A</strong> on the <strong>McLab2</strong> board — and the built-in example route, so you do not need to write or compile any code for your first run. Once this works, every other tutorial on this site follows the same flow.</p>
<h2>What you need</h2>
<ul>
<li>PICSimLab 0.9.3 installed — follow the <a href="https://picsimlab.com/install-picsimlab-windows/">Windows install guide</a> (or the <a href="https://picsimlab.com/download/">download page</a> for Linux and macOS). No compiler is needed for this first run; compiling your own code comes in the workflow guides linked at the end.</li>
<li>About ten minutes. Nothing else: the example firmware ships with PICSimLab.</li>
</ul>
<p>No install possible right now? The <a href="https://picsimlab.com/online/">online version</a> runs the same simulator in a browser tab with documented limits (no debugging, no serial, about half desktop speed) — the steps below for selecting a board and loading an example are the same idea, with files loaded by drag and drop or the Load button.</p>
<h2>Step 1: Start PICSimLab and select the board</h2>
<p>Launch PICSimLab. Select the <strong>McLab2</strong> board and set the microcontroller to <strong>PIC16F877A</strong>. Board selection comes first in every PICSimLab session: the board defines which microcontrollers you can pick and how the firmware you load will be interpreted. McLab2 officially supports the PIC16F877A (along with the PIC16F777, PIC18F452, PIC18F4520, PIC18F4550 and PIC18F4620); the PICGenios board supports the same set if you prefer it.</p>
<h2>Step 2: Open a built-in example</h2>
<p>Open the examples from the <em>Help &rarr; Examples</em> menu and choose an McLab2 example written for the PIC16F877A — a blink or LED example is ideal for a first run. The examples are the fastest way to reach a known-good simulation, because the firmware, board and microcontroller already match. Alternatively, if you have already compiled a project, load your own firmware instead — the <a href="https://picsimlab.com/load-hex-file-picsimlab/">hex loading guide</a> covers that path.</p>
<h2>Step 3: Run the simulation</h2>
<p>Start the simulation with the run control. A working example shows immediate life: board LEDs change state, and the simulated clock starts counting. If absolutely nothing happens, do not guess — work through the <a href="https://picsimlab.com/picsimlab-simulation-not-running/">simulation not running checklist</a> (run state, reset, clock and workspace checks) before changing anything else.</p>
<h2>Step 4: Add an LED spare part and watch a pin</h2>
<p>Board LEDs are fixed to the board. To watch a pin of <em>your</em> choosing, add a spare part:</p>
<ol>
<li>Open <em>Modules &rarr; Spare parts</em>.</li>
<li>From the <em>Outputs</em> category, add <strong>LEDs</strong> (a bank of 8 red LEDs).</li>
<li>Right-click the part, open <strong>Properties</strong>, and connect the first LED to the pin your example toggles (for a typical blink example, check which port pin the example drives — RB0 is a common choice).</li>
<li>Run the simulation again and watch the LED follow the pin. Right-clicking any spare part also gives you Move, Rotate, Delete and Help.</li>
</ol>
<p>You have now used the three building blocks of every PICSimLab session: a board, a firmware file and spare parts wired in Properties. The dedicated <a href="https://picsimlab.com/picsimlab-led-push-button-spare-parts/">LED and push button spare parts tutorial</a> goes further, and the <a href="https://picsimlab.com/pic16f877a-blink-led-picsimlab/">PIC16F877A LED blink tutorial</a> shows the same blink written and compiled by you, end to end.</p>
<h2>Step 5: Stop, reset, experiment</h2>
<p>Stop the simulation, change one thing — a different example, a different LED pin in Properties, a push button part wired to an input pin — and run again. Small, reversible experiments are how the spare-parts system clicks. When you are ready to run your own code, continue with the workflow that matches your chip family: <a href="https://picsimlab.com/mplab-x-xc8-picsimlab-workflow/">MPLAB X + XC8 for PIC</a> or <a href="https://picsimlab.com/arduino-ide-picsimlab-workflow/">PlatformIO / Arduino IDE for AVR, STM32 and ESP32</a>. The full beginner path is collected on the <a href="https://picsimlab.com/getting-started/">getting started page</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>HD44780 LCD over I2C (PCF8574) in PICSimLab</title>
		<link>https://picsimlab.com/picsimlab-lcd-i2c-pcf8574/</link>
		
		<dc:creator><![CDATA[Admin]]></dc:creator>
		<pubDate>Thu, 22 Oct 2026 04:01:53 +0000</pubDate>
				<category><![CDATA[Tutorials]]></category>
		<guid isPermaLink="false">https://picsimlab.com/picsimlab-lcd-i2c-pcf8574/</guid>

					<description><![CDATA[HD44780 LCD over I2C (PCF8574) in PICSimLab The parallel HD44780 LCD uses six or more pins. The I2C version of the display — an HD44780 with a PCF8574 I/O expander backpack — needs only two: SDA and SCL. PICSimLab models this directly with its LCD hd44780 I2C spare part, described in the documentation as a...]]></description>
										<content:encoded><![CDATA[<h1>HD44780 LCD over I2C (PCF8574) in PICSimLab</h1>
<p>The parallel HD44780 LCD uses six or more pins. The I2C version of the display — an HD44780 with a <strong>PCF8574</strong> I/O expander backpack — needs only two: SDA and SCL. PICSimLab models this directly with its <strong>LCD hd44780 I2C</strong> spare part, described in the documentation as a text display HD44780 connected to one PCF8574 I2C converter. This tutorial drives it from a PIC16F877A&#8217;s hardware I2C (MSSP).</p>
<h2>What you need</h2>
<ul>
<li>PICSimLab 0.9.3 — see the <a href="https://picsimlab.com/download/">download page</a>.</li>
<li>MPLAB X IDE and the XC8 compiler.</li>
<li>Board: <strong>McLab2</strong> or <strong>PICGenios</strong>, microcontroller PIC16F877A.</li>
<li>One LCD hd44780 I2C spare part (Outputs category). PICSimLab also lists a standalone IO PCF8574 expander part if you want to model the chip separately.</li>
<li>Helpful first: the <a href="https://picsimlab.com/pic16f877a-lcd-hd44780-picsimlab/">parallel LCD tutorial</a> — the HD44780 commands are identical, only the transport changes.</li>
</ul>
<h2>Wiring used in this tutorial (example)</h2>
<ul>
<li>SCL &rarr; RC3, SDA &rarr; RC4 (the PIC16F877A MSSP I2C pins)</li>
<li>PCF8574 address in the example code: 0x27 (write address 0x4E). This is the most common backpack address; if the part in your configuration uses a different address, change the define — the rest of the code is unaffected.</li>
</ul>
<h2>Steps</h2>
<h3>1. Generate the project and add the display</h3>
<p>Create the MPLAB X project for the PIC16F877A. Open <em>Modules &rarr; Spare parts</em>, add <em>Outputs &rarr; LCD hd44780 I2C</em> and connect SCL and SDA in its Properties to RC3 and RC4.</p>
<h3>2. Understand the PCF8574 pin mapping</h3>
<p>The expander byte sent over I2C maps to the LCD like this in the standard backpack layout used by the example: bit 0 = RS, bit 1 = RW (kept 0, write only), bit 2 = EN, bit 3 = backlight (1 = on), bits 4–7 = data D4–D7. Each LCD nibble is written by setting the data bits and pulsing EN within the I2C bytes — no extra GPIO needed.</p>
<h3>3. Initialise I2C, then the LCD</h3>
<p>The example configures the MSSP as an I2C master at 100 kHz for a 20 MHz clock (<code>SSPADD = 49</code>), then performs the standard HD44780 4-bit initialisation through the backpack. After that, printing is the same <code>lcd_puts()</code> pattern as the parallel version.</p>
<h3>4. Build, load and run</h3>
<p>Build in MPLAB X, load the <code>.hex</code> and start the simulation. &#8220;I2C LCD OK&#8221; should appear on the first line, with the second line showing the backpack address the code used.</p>
<h2>Example code (XC8)</h2>
<pre><code>// Example: HD44780 LCD via PCF8574 I2C backpack - PIC16F877A, XC8
// SCL=RC3, SDA=RC4. Backpack bits: P0=RS P1=RW P2=EN P3=BL P4-P7=D4-D7
#pragma config FOSC = HS
#pragma config WDTE = OFF
#pragma config PWRTE = ON
#pragma config BOREN = ON
#pragma config LVP = OFF
#pragma config CPD = OFF
#pragma config WRT = OFF
#pragma config CP = OFF

#include &lt;xc.h&gt;
#define _XTAL_FREQ 20000000     // Example: match the board clock
#define LCD_ADDR 0x4E           // Example: PCF8574 at 0x27, write address

void i2c_init(void) {
    TRISCbits.TRISC3 = 1;       // SCL input (MSSP controls it)
    TRISCbits.TRISC4 = 1;       // SDA input
    SSPCON = 0x28;              // I2C master mode, module on
    SSPCON2 = 0x00;
    SSPSTAT = 0x00;
    SSPADD = 49;                // 100 kHz at 20 MHz Fosc
}

void i2c_start(void) { SSPCON2bits.SEN = 1; while (SSPCON2bits.SEN) { } }
void i2c_stop(void)  { SSPCON2bits.PEN = 1; while (SSPCON2bits.PEN) { } }

void i2c_write(unsigned char b) {
    SSPBUF = b;
    while (!PIR1bits.SSPIF) { }
    PIR1bits.SSPIF = 0;
}

static void lcd_expander(unsigned char data) {
    i2c_start();
    i2c_write(LCD_ADDR);
    i2c_write(data);
    i2c_stop();
}

// Send one nibble with EN pulse; rs = 0 command, 1 data; backlight on
static void lcd_nibble(unsigned char nibble, unsigned char rs) {
    unsigned char base = (unsigned char)((nibble &amp; 0xF0) | 0x08 | rs);
    lcd_expander((unsigned char)(base | 0x04));  // EN high
    __delay_us(2);
    lcd_expander(base);                          // EN low
    __delay_us(100);
}

static void lcd_byte(unsigned char b, unsigned char rs) {
    lcd_nibble(b &amp; 0xF0, rs);
    lcd_nibble((unsigned char)(b &lt;&lt; 4), rs);
    __delay_ms(2);
}

void lcd_cmd(unsigned char c) { lcd_byte(c, 0); }
void lcd_putc(char ch)        { lcd_byte((unsigned char)ch, 1); }
void lcd_puts(const char *s)  { while (*s) lcd_putc(*s++); }

void lcd_init(void) {
    __delay_ms(50);
    lcd_nibble(0x30, 0); __delay_ms(5);
    lcd_nibble(0x30, 0); __delay_us(200);
    lcd_nibble(0x30, 0); __delay_us(200);
    lcd_nibble(0x20, 0);        // 4-bit mode
    lcd_cmd(0x28);              // 4-bit, 2 lines
    lcd_cmd(0x0C);              // display on
    lcd_cmd(0x06);              // entry mode
    lcd_cmd(0x01);              // clear
    __delay_ms(2);
}

void main(void) {
    i2c_init();
    lcd_init();
    lcd_puts("I2C LCD OK");
    lcd_cmd(0xC0);              // line 2
    lcd_puts("PCF8574 @0x27");
    while (1) { }
}</code></pre>
<h2>Try next</h2>
<ul>
<li><a href="https://picsimlab.com/pic16f877a-lcd-hd44780-picsimlab/">Parallel HD44780 LCD</a> — compare the two transports side by side.</li>
<li><a href="https://picsimlab.com/pic16f877a-eeprom-picsimlab/">EEPROM tutorial</a> — then try the MEM 24CXXX I2C EEPROM spare part with the same bus code.</li>
<li><a href="https://picsimlab.com/picsimlab-w5500-ethernet-spare-part/">ETH W5500 spare part</a> — the SPI counterpart to this I2C exercise.</li>
</ul>
<h2>Troubleshooting</h2>
<p><strong>The display never responds.</strong> Address first: a backpack at 0x27 needs write address 0x4E; at 0x3F it is 0x7E. Then check SDA and SCL are not swapped in the part&#8217;s Properties — I2C fails silently when they are.</p>
<p><strong>Characters appear but the backlight stays off or text is garbled.</strong> The backlight is bit 3 of every expander byte (kept set in the example). Garbled text with a working backlight points at the nibble/EN pulse code — compare it against the parallel tutorial&#8217;s driver, which shares the same HD44780 command set.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>The ETH W5500 Spare Part in PICSimLab: What It Does</title>
		<link>https://picsimlab.com/picsimlab-w5500-ethernet-spare-part/</link>
		
		<dc:creator><![CDATA[Admin]]></dc:creator>
		<pubDate>Thu, 22 Oct 2026 04:01:43 +0000</pubDate>
				<category><![CDATA[Tutorials]]></category>
		<guid isPermaLink="false">https://picsimlab.com/picsimlab-w5500-ethernet-spare-part/</guid>

					<description><![CDATA[The ETH W5500 Spare Part in PICSimLab: What It Does Among PICSimLab&#8217;s spare parts, the ETH w5500 (in the Others category) is the one most often oversold in third-party tutorials. This page sticks to what the official documentation supports: the part adds a W5500 Ethernet shield model to your simulation. What it does not do...]]></description>
										<content:encoded><![CDATA[<h1>The ETH W5500 Spare Part in PICSimLab: What It Does</h1>
<p>Among PICSimLab&#8217;s spare parts, the <strong>ETH w5500</strong> (in the Others category) is the one most often oversold in third-party tutorials. This page sticks to what the official documentation supports: the part adds a W5500 Ethernet shield model to your simulation. What it does not do is write your network firmware for you — and the documentation does not promise full network-stack emulation. Here is how to set the part up correctly and what to expect from it.</p>
<h2>What you need</h2>
<ul>
<li>PICSimLab 0.9.3 — see the <a href="https://picsimlab.com/download/">download page</a>.</li>
<li>MPLAB X IDE and the XC8 compiler.</li>
<li>Board: <strong>McLab2</strong> or <strong>PICGenios</strong> with a PIC that has an MSSP SPI module — this tutorial uses the PIC16F877A as the example host.</li>
<li>One ETH w5500 spare part, and a W5500 driver for your firmware project (see step 3 — PICSimLab does not supply application firmware).</li>
<li>Recommended first: the <a href="https://picsimlab.com/pic16f877a-uart-serial-picsimlab/">UART tutorial</a>, so you have serial logging while bringing up SPI devices.</li>
</ul>
<h2>Wiring used in this tutorial (example)</h2>
<p>The W5500 is an SPI device. On the PIC16F877A the hardware SPI (MSSP) pins are:</p>
<ul>
<li>SCK &rarr; RC3, SDI (MISO) &rarr; RC4, SDO (MOSI) &rarr; RC5</li>
<li>Chip select (example) &rarr; RB0 — a normal GPIO you drive yourself</li>
</ul>
<p>Open the ETH w5500 part&#8217;s Properties (right-click the part after adding it) and connect its SPI lines to these pins. The chip-select pin is your choice; just keep the firmware and the Properties window in agreement.</p>
<h2>Steps</h2>
<h3>1. Generate the project and add the part</h3>
<p>Create the MPLAB X project for the PIC16F877A. Open <em>Modules &rarr; Spare parts</em> and add <em>Others &rarr; ETH w5500</em>. Set its connections in Properties as above, and save the spare-parts configuration (<code>.pcf</code>) from the window&#8217;s File menu so the wiring survives restarts.</p>
<h3>2. Bring up SPI first, without the network stack</h3>
<p>Before any Ethernet code, prove the SPI bus: initialise the MSSP as an SPI master and read a known W5500 register (the VERSIONR register, which a real W5500 answers with 0x04) in a tiny test program, logging the result over the UART from the earlier tutorial. If the version read fails in simulation, the problem is wiring or SPI mode — not your TCP code.</p>
<h3>3. Add a W5500 driver to your firmware</h3>
<p>PICSimLab simulates hardware; it does not include your application. A W5500 driver (the chip vendor&#8217;s ioLibrary is the usual starting point on real projects) must be ported to XC8 and to your SPI read/write functions, with realistic expectations about effort: small PICs have limited RAM for socket buffers, so keep the test program minimal — for example, initialise the chip, set a static IP configuration in code and open one socket.</p>
<h3>4. Set honest expectations for the simulation</h3>
<p>The official PICSimLab spare-parts documentation confirms the ETH w5500 part exists and how it is added; it does not publish a coverage matrix for network protocols. Treat the simulation as a way to develop and debug your SPI driver and program flow. Anything that depends on a real LAN — DHCP servers, real peers, internet services, throughput — belongs on real hardware with a real W5500. Tutorials that promise full Ethernet projects &#8220;just like real hardware&#8221; in the simulator are going beyond the documentation.</p>
<h2>Example code: SPI version check (XC8)</h2>
<pre><code>// Example: MSSP SPI master + W5500 version register read
// PIC16F877A, XC8. SCK=RC3, SDI=RC4, SDO=RC5, CS=RB0 (example)
#pragma config FOSC = HS
#pragma config WDTE = OFF
#pragma config PWRTE = ON
#pragma config BOREN = ON
#pragma config LVP = OFF
#pragma config CPD = OFF
#pragma config WRT = OFF
#pragma config CP = OFF

#include &lt;xc.h&gt;
#define _XTAL_FREQ 20000000     // Example: match the board clock

#define W5500_CS PORTBbits.RB0

void spi_init(void) {
    TRISCbits.TRISC3 = 0;       // SCK output
    TRISCbits.TRISC4 = 1;       // SDI input
    TRISCbits.TRISC5 = 0;       // SDO output
    TRISBbits.TRISB0 = 0;       // CS output
    W5500_CS = 1;               // deselected
    SSPSTAT = 0x40;             // CKE=1, sample at middle
    SSPCON = 0x21;              // SPI master, Fosc/16, idle low
}

unsigned char spi_transfer(unsigned char b) {
    SSPBUF = b;
    while (!SSPSTATbits.BF) { }
    return SSPBUF;
}

// W5500 VERSIONR is at block 0, address 0x0039; value should be 0x04
unsigned char w5500_read_version(void) {
    W5500_CS = 0;
    spi_transfer(0x00);         // address high byte
    spi_transfer(0x39);         // address low byte
    spi_transfer(0x00);         // read, block 0
    unsigned char v = spi_transfer(0xFF);
    W5500_CS = 1;
    return v;
}</code></pre>
<p>Use <code>w5500_read_version()</code> from your test main with the result sent to the UART or shown on LEDs — it separates &#8220;SPI works&#8221; from &#8220;network stack works&#8221;, which saves hours.</p>
<h2>Try next</h2>
<ul>
<li><a href="https://picsimlab.com/pic16f877a-uart-serial-picsimlab/">UART serial</a> — the debug channel every network bring-up needs.</li>
<li><a href="https://picsimlab.com/picsimlab-lcd-i2c-pcf8574/">LCD over I2C (PCF8574)</a> — another bus peripheral, with a gentler learning curve than Ethernet.</li>
<li><a href="https://picsimlab.com/picsimlab-oscilloscope/">Oscilloscope basics</a> — sanity-check SCK and chip-select timing.</li>
</ul>
<h2>Troubleshooting</h2>
<p><strong>The version register does not read 0x04.</strong> Work the SPI checklist: CS actually toggling, SDI/SDO not swapped in Properties, CKE/CKP settings, and the correct three-byte header before the data byte. Change one thing at a time and retest.</p>
<p><strong>The driver compiles but nothing network-related happens.</strong> That is the expected boundary of the simulation if your code depends on a live network. Keep driver and SPI debugging in PICSimLab; schedule protocol testing on real hardware.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Control a Stepper Motor with the PICSimLab Step Motor Spare Part</title>
		<link>https://picsimlab.com/picsimlab-stepper-motor-spare-part/</link>
		
		<dc:creator><![CDATA[Admin]]></dc:creator>
		<pubDate>Thu, 22 Oct 2026 04:01:33 +0000</pubDate>
				<category><![CDATA[Tutorials]]></category>
		<guid isPermaLink="false">https://picsimlab.com/picsimlab-stepper-motor-spare-part/</guid>

					<description><![CDATA[Control a Stepper Motor with the PICSimLab Step Motor Spare Part Stepper motors move in discrete steps driven by a repeating coil pattern, which makes them a clean simulation subject: if the sequence and timing are right, the motor turns; if not, it jitters. PICSimLab&#8217;s Step Motor spare part lets a PIC16F877A drive a virtual...]]></description>
										<content:encoded><![CDATA[<h1>Control a Stepper Motor with the PICSimLab Step Motor Spare Part</h1>
<p>Stepper motors move in discrete steps driven by a repeating coil pattern, which makes them a clean simulation subject: if the sequence and timing are right, the motor turns; if not, it jitters. PICSimLab&#8217;s <strong>Step Motor</strong> spare part lets a PIC16F877A drive a virtual stepper so you can learn full-step sequencing without a motor, a driver board or a power supply.</p>
<h2>What you need</h2>
<ul>
<li>PICSimLab 0.9.3 — see the <a href="https://picsimlab.com/download/">download page</a>.</li>
<li>MPLAB X IDE and the XC8 compiler.</li>
<li>Board: <strong>McLab2</strong> or <strong>PICGenios</strong>, microcontroller PIC16F877A.</li>
<li>One Step Motor spare part (Outputs category).</li>
</ul>
<h2>Wiring used in this tutorial (example)</h2>
<ul>
<li>Step Motor control inputs 1–4 &rarr; RD0–RD3</li>
</ul>
<p>Connect the four control lines in the part&#8217;s Properties window (right-click the part &rarr; Properties). A note for real hardware: a microcontroller pin cannot drive motor coils directly — a real build needs a driver stage (a transistor array or H-bridge module) between the PIC and the motor. The spare part models the motor side in simulation, which is precisely why it is handy for learning the sequence logic first.</p>
<h2>Steps</h2>
<h3>1. Generate the project and add the part</h3>
<p>Create the MPLAB X project for the PIC16F877A with the Code Project Wizard. Open <em>Modules &rarr; Spare parts</em>, add <em>Outputs &rarr; Step Motor</em> and wire its four inputs to RD0–RD3 in Properties.</p>
<h3>2. Learn the full-step sequence</h3>
<p>Two-phase-on full stepping energises two coils at a time in this repeating pattern on RD3–RD0: <code>1001, 1100, 0110, 0011</code> (0x09, 0x0C, 0x06, 0x03). Stepping forward through the table turns the motor one way; stepping backward reverses it. The delay between steps sets the speed — too short and a real motor would skip steps, which is a habit worth building even in simulation.</p>
<h3>3. Build, load and run</h3>
<p>Build in MPLAB X, load the <code>.hex</code> and run. The example rotates forward for 48 steps, pauses, then rotates back — watch the motor part respond, and probe RD0–RD3 with <em>Modules &rarr; Oscilloscope</em> if you want to see the four phase signals shift along.</p>
<h2>Example code (XC8)</h2>
<pre><code>// Example: full-step stepper drive on RD0-RD3 - PIC16F877A, XC8
#pragma config FOSC = HS
#pragma config WDTE = OFF
#pragma config PWRTE = ON
#pragma config BOREN = ON
#pragma config LVP = OFF
#pragma config CPD = OFF
#pragma config WRT = OFF
#pragma config CP = OFF

#include &lt;xc.h&gt;
#define _XTAL_FREQ 20000000     // Example: match the board clock

// Two-phase-on full-step sequence
static const unsigned char step_table[4] = {0x09, 0x0C, 0x06, 0x03};
static unsigned char step_index = 0;

void step_forward(void) {
    step_index = (step_index + 1) &amp; 0x03;
    PORTD = step_table[step_index];
}

void step_reverse(void) {
    step_index = (step_index - 1) &amp; 0x03;
    PORTD = step_table[step_index];
}

void main(void) {
    TRISD = 0x00;               // RD0-RD3 outputs to the Step Motor part
    PORTD = 0x00;
    while (1) {
        for (unsigned char i = 0; i &lt; 48; i++) {  // forward 48 steps
            step_forward();
            __delay_ms(20);                       // step rate = speed
        }
        __delay_ms(500);
        for (unsigned char i = 0; i &lt; 48; i++) {  // and back again
            step_reverse();
            __delay_ms(20);
        }
        __delay_ms(500);
    }
}</code></pre>
<h2>Try next</h2>
<ul>
<li><a href="https://picsimlab.com/pic16f877a-timers-interrupts-picsimlab/">Timers and interrupts</a> — generate the step pulses from a timer for jitter-free speed.</li>
<li><a href="https://picsimlab.com/picsimlab-oscilloscope/">Oscilloscope basics</a> — verify the spacing of the four phase outputs.</li>
<li><a href="https://picsimlab.com/pic16f877a-adc-potentiometer-picsimlab/">ADC potentiometer</a> — use a knob to set the motor speed.</li>
</ul>
<h2>Troubleshooting</h2>
<p><strong>The motor vibrates but does not turn.</strong> The phase order is wrong: one swapped control line in the part&#8217;s Properties (or in the step table) produces exactly this symptom. Check the RD0–RD3 mapping first.</p>
<p><strong>It turns the wrong way.</strong> Not a bug — reverse the table order (or swap the forward/reverse functions). Direction is purely a matter of sequence order in a stepper.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Using the PICSimLab Oscilloscope: Two-Channel Basics</title>
		<link>https://picsimlab.com/picsimlab-oscilloscope/</link>
		
		<dc:creator><![CDATA[Admin]]></dc:creator>
		<pubDate>Thu, 22 Oct 2026 04:01:22 +0000</pubDate>
				<category><![CDATA[Tutorials]]></category>
		<guid isPermaLink="false">https://picsimlab.com/picsimlab-oscilloscope/</guid>

					<description><![CDATA[Using the PICSimLab Oscilloscope: Two-Channel Basics PICSimLab includes a built-in oscilloscope, and learning it early makes every other tutorial easier: instead of guessing whether a pin toggles at the right speed, you measure it. Be clear about what it is, though — per the official documentation it is a basic two-channel oscilloscope for viewing the...]]></description>
										<content:encoded><![CDATA[<h1>Using the PICSimLab Oscilloscope: Two-Channel Basics</h1>
<p>PICSimLab includes a built-in oscilloscope, and learning it early makes every other tutorial easier: instead of guessing whether a pin toggles at the right speed, you measure it. Be clear about what it is, though — per the official documentation it is a <strong>basic two-channel oscilloscope</strong> for viewing the signal on any microcontroller pin, not a professional bench instrument. Within that scope, it is genuinely useful.</p>
<h2>What you need</h2>
<ul>
<li>PICSimLab 0.9.3 — see the <a href="https://picsimlab.com/download/">download page</a>.</li>
<li>Any running simulation with a changing pin. The <a href="https://picsimlab.com/pic16f877a-blink-led-picsimlab/">LED blink project</a> (RB0 toggling every 500 ms) is the ideal first signal; the <a href="https://picsimlab.com/pic16f877a-timers-interrupts-picsimlab/">timer interrupt project</a> works too.</li>
<li>No spare parts are required — the oscilloscope is its own module, not a spare part.</li>
</ul>
<h2>Steps</h2>
<h3>1. Start a simulation with a known signal</h3>
<p>Load the blink hex file, start the simulation and confirm the LED toggles. A measurement is only meaningful against a signal you can predict: RB0 should be a square wave with a period of about one second (500 ms high, 500 ms low).</p>
<h3>2. Open the oscilloscope</h3>
<p>Open <em>Modules &rarr; Oscilloscope</em>. The oscilloscope window shows two channels; assign the first channel to pin RB0 of the microcontroller. Adjust the time base until one or two full cycles fit on screen — for a 1 Hz signal you need a much slower sweep than the defaults used for kilohertz signals.</p>
<h3>3. Add measurements</h3>
<p>The oscilloscope supports <strong>up to 4 simultaneous measurements</strong>, chosen from: Vmax, Vmin, Vavg, Vrms, Frequency, Duty cycle, Pos. cycle, Neg. cycle and Full cycle. For the blink signal, add <strong>Frequency</strong> and <strong>Duty cycle</strong>: expect about 1 Hz and about 50%. Add Full cycle as a third measurement to see the period in time units.</p>
<h3>4. Compare two pins on two channels</h3>
<p>Assign the second channel to another live pin — for example the Timer0 interrupt LED project running alongside a delay-based blink on a second pin, or the TX pin from the <a href="https://picsimlab.com/pic16f877a-uart-serial-picsimlab/">UART tutorial</a> while it sends a character. Two channels are enough to check which signal changes first and whether two outputs stay in step.</p>
<h3>5. Measure a PWM-style signal</h3>
<p>Generate a faster toggling signal (shorten the blink delays, or use a CCP PWM exercise) and re-measure: Frequency and Duty cycle now change with your code, which is exactly the feedback loop you want when tuning timers. Remember the simulation speed caveat from the documentation: signals are only as accurate as the simulated clock, so verify your <code>_XTAL_FREQ</code> assumption matches the board configuration.</p>
<h2>What the oscilloscope is not</h2>
<p>It does not turn PICSimLab into a logic analyser suite or a calibrated measurement instrument, and it shows simulated pin levels — idealised logic signals from the simulator core, not the analogue behaviour (ringing, rise times, loading) of a real circuit. Use it to verify timing, frequency, duty cycle and sequencing in your firmware; use real instruments on real hardware for signal integrity.</p>
<h2>Try next</h2>
<ul>
<li><a href="https://picsimlab.com/pic16f877a-timers-interrupts-picsimlab/">Timers and interrupts</a> — produce precise signals worth measuring.</li>
<li><a href="https://picsimlab.com/pic16f877a-adc-potentiometer-picsimlab/">ADC potentiometer</a> — probe the analog input pin while you turn the knob.</li>
<li><a href="https://picsimlab.com/picsimlab-stepper-motor-spare-part/">Step Motor spare part</a> — check the four step pulses stay evenly spaced.</li>
</ul>
<h2>Troubleshooting</h2>
<p><strong>The trace is a flat line.</strong> The simulation is stopped, the channel is assigned to the wrong pin, or the time base is so fast that a 1 Hz signal looks frozen. Confirm the LED itself toggles, then slow the sweep down.</p>
<p><strong>Frequency reads about double or half the expected value.</strong> Your code&#8217;s timing assumption is off — most often <code>_XTAL_FREQ</code> not matching the board clock configured in PICSimLab. Fix the define, rebuild, reload and measure again.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>LED on RB0 and RC0 with a Push Button in PICSimLab Spare Parts</title>
		<link>https://picsimlab.com/picsimlab-led-push-button-spare-parts/</link>
		
		<dc:creator><![CDATA[Admin]]></dc:creator>
		<pubDate>Thu, 22 Oct 2026 04:01:12 +0000</pubDate>
				<category><![CDATA[Tutorials]]></category>
		<guid isPermaLink="false">https://picsimlab.com/picsimlab-led-push-button-spare-parts/</guid>

					<description><![CDATA[LED on RB0 and RC0 with a Push Button in PICSimLab Spare Parts &#8220;LED on RB0, LED on RC0, push button to control them&#8221; is one of the most searched PICSimLab exercises — and a perfect spare-parts workout. This tutorial wires an LED to RB0, a second LED to RC0 and a push button that...]]></description>
										<content:encoded><![CDATA[<h1>LED on RB0 and RC0 with a Push Button in PICSimLab Spare Parts</h1>
<p>&#8220;LED on RB0, LED on RC0, push button to control them&#8221; is one of the most searched PICSimLab exercises — and a perfect spare-parts workout. This tutorial wires an <strong>LED to RB0</strong>, a second <strong>LED to RC0</strong> and a <strong>push button</strong> that drives them, using PICSimLab&#8217;s LEDs and Push Buttons spare parts with a PIC16F877A. If you can do this, you understand digital outputs, digital inputs and part wiring — the three skills every other tutorial here builds on.</p>
<h2>What you need</h2>
<ul>
<li>PICSimLab 0.9.3 — see the <a href="https://picsimlab.com/download/">download page</a>.</li>
<li>MPLAB X IDE and the XC8 compiler.</li>
<li>Board: <strong>McLab2</strong> or <strong>PICGenios</strong>, microcontroller PIC16F877A (the Breadboard also works for this exercise).</li>
<li>Two spare parts: <strong>LEDs</strong> (Outputs) and <strong>Push Buttons</strong> (Inputs).</li>
</ul>
<h2>Wiring: LED RB0, LED RC0, push button on RD0</h2>
<ul>
<li>LEDs part, LED 1 &rarr; <strong>RB0</strong></li>
<li>LEDs part, LED 2 &rarr; <strong>RC0</strong></li>
<li>Push Buttons part, button 1 &rarr; <strong>RD0</strong> (the input the code polls)</li>
</ul>
<p>Add both parts from <em>Modules &rarr; Spare parts</em>, then right-click each part, open <strong>Properties</strong> and set these connections. The behaviour in the example: while the button is held, the RB0 LED follows the button and the RC0 LED lights too; a quick press-and-release toggles the RC0 LED state so you can also test edge detection. Adjust the button&#8217;s active level in Properties if your part defaults differ — the code comments mark where to invert the test.</p>
<h2>Steps</h2>
<h3>1. Generate the project</h3>
<p>Select the board and PIC16F877A, then generate the MPLAB X project with the Code Project Wizard.</p>
<h3>2. Configure directions</h3>
<p>RB0 and RC0 are outputs (<code>TRISBbits.TRISB0 = 0</code>, <code>TRISCbits.TRISC0 = 0</code>); RD0 is an input (<code>TRISDbits.TRISD0 = 1</code>). Ninety percent of &#8220;the LED does nothing&#8221; reports are a direction bit or a Properties connection — check those before suspecting the simulator.</p>
<h3>3. Build, load and click</h3>
<p>Build in MPLAB X, load the <code>.hex</code> and run. Click and hold the button in the spare-parts window: RB0 follows the button live. Release and click again to see RC0 change state per press.</p>
<h2>Example code (XC8)</h2>
<pre><code>// Example: LED on RB0 + LED on RC0 + push button - PIC16F877A, XC8
// Button on RD0 (example: pressed = logic 1; invert the tests if
// your Push Buttons part is configured active-low)
#pragma config FOSC = HS
#pragma config WDTE = OFF
#pragma config PWRTE = ON
#pragma config BOREN = ON
#pragma config LVP = OFF
#pragma config CPD = OFF
#pragma config WRT = OFF
#pragma config CP = OFF

#include &lt;xc.h&gt;
#define _XTAL_FREQ 20000000     // Example: match the board clock

#define BUTTON PORTDbits.RD0

void main(void) {
    TRISBbits.TRISB0 = 0;       // RB0 output -> LED 1
    TRISCbits.TRISC0 = 0;       // RC0 output -> LED 2
    TRISDbits.TRISD0 = 1;       // RD0 input  -> push button
    PORTBbits.RB0 = 0;
    PORTCbits.RC0 = 0;
    unsigned char rc0_state = 0;
    unsigned char last_button = 0;
    while (1) {
        unsigned char pressed = BUTTON;
        PORTBbits.RB0 = pressed;              // RB0 LED follows the button
        if (pressed &amp;&amp; !last_button) {        // rising edge: one toggle
            rc0_state = !rc0_state;
            PORTCbits.RC0 = rc0_state;        // RC0 LED toggles per press
            __delay_ms(30);                   // debounce
        }
        last_button = pressed;
    }
}</code></pre>
<h2>Try next</h2>
<ul>
<li><a href="https://picsimlab.com/pic16f877a-matrix-keypad-picsimlab/">Matrix keypad</a> — from one button to sixteen keys on eight pins.</li>
<li><a href="https://picsimlab.com/pic16f877a-eeprom-picsimlab/">EEPROM counter</a> — count the button presses and keep the count across resets.</li>
<li><a href="https://picsimlab.com/pic16f877a-timers-interrupts-picsimlab/">Timers and interrupts</a> — react to the button in an interrupt instead of polling.</li>
</ul>
<h2>Troubleshooting</h2>
<p><strong>The RB0 LED is on when it should be off (or the reverse).</strong> The button part&#8217;s active level does not match the code&#8217;s assumption. Either flip the connection behaviour in the part&#8217;s Properties or invert the <code>pressed</code> test (<code>pressed = !BUTTON</code>) and rebuild.</p>
<p><strong>RC0 flickers instead of toggling once per press.</strong> Contact bounce plus a held button: the edge-detect and debounce in the example handle the normal case — if it still flickers, increase the debounce delay and make sure you are not retriggering by holding the mouse button down.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>PIC18F4550 First Project in PICSimLab (McLab2 / PICGenios)</title>
		<link>https://picsimlab.com/pic18f4550-picsimlab-first-project/</link>
		
		<dc:creator><![CDATA[Admin]]></dc:creator>
		<pubDate>Thu, 22 Oct 2026 04:01:02 +0000</pubDate>
				<category><![CDATA[Tutorials]]></category>
		<guid isPermaLink="false">https://picsimlab.com/pic18f4550-picsimlab-first-project/</guid>

					<description><![CDATA[PIC18F4550 First Project in PICSimLab (McLab2 / PICGenios) The PIC18F4550 is one of the six microcontrollers officially supported by the McLab2 and PICGenios boards in PICSimLab, and moving from the PIC16F877A to it is a natural second step: the workflow is identical, only the chip family, configuration words and port registers change. This tutorial takes...]]></description>
										<content:encoded><![CDATA[<h1>PIC18F4550 First Project in PICSimLab (McLab2 / PICGenios)</h1>
<p>The PIC18F4550 is one of the six microcontrollers officially supported by the McLab2 and PICGenios boards in PICSimLab, and moving from the PIC16F877A to it is a natural second step: the workflow is identical, only the chip family, configuration words and port registers change. This tutorial takes you from an empty project to a running LED blink on the PIC18F4550 — and is honest about where it stops.</p>
<h2>What you need</h2>
<ul>
<li>PICSimLab 0.9.3 — see the <a href="https://picsimlab.com/download/">download page</a>.</li>
<li>MPLAB X IDE and the XC8 compiler. As with the PIC16F, the Code Project Wizard generates an MPLAB X project for PIC18F boards.</li>
<li>Board: <strong>McLab2</strong> or <strong>PICGenios</strong>, microcontroller <strong>PIC18F4550</strong>.</li>
<li>One LEDs spare part connected to RB0.</li>
</ul>
<h2>What is different from the PIC16F877A</h2>
<ul>
<li><strong>LAT registers:</strong> on PIC18 you write outputs through <code>LATB</code> and read inputs through <code>PORTB</code>. Writing to PORTB directly (PIC16 style) causes read-modify-write surprises on loaded pins.</li>
<li><strong>Configuration words:</strong> PIC18F4550 uses several CONFIG registers; the example sets the essential ones (oscillator, watchdog off, low-voltage programming off). USB-related configuration is deliberately left at defaults because this tutorial does not use USB.</li>
<li><strong>Analog defaults:</strong> several pins power up as analog inputs; the example sets <code>ADCON1</code> so PORTB pins behave as digital I/O.</li>
</ul>
<h2>Steps</h2>
<h3>1. Select the board and the PIC18F4550</h3>
<p>Start PICSimLab, choose the McLab2 board (or PICGenios) and set the microcontroller to PIC18F4550. Generating the project after this selection is what makes the wizard target the right chip.</p>
<h3>2. Generate and build the project</h3>
<p>Use the Code Project Wizard to generate the MPLAB X project, paste in the example code, and build. MPLAB X produces the <code>.hex</code> file as usual. The official documentation also points to board example sources in MPLAB X + XC8 from <em>Help &rarr; Examples</em> if you want a larger starting point.</p>
<h3>3. Add the LED and load the hex</h3>
<p>Open <em>Modules &rarr; Spare parts</em>, add <em>Outputs &rarr; LEDs</em> and connect the first LED to RB0 in Properties. Load the hex file and start the simulation: the LED blinks once per second.</p>
<h3>4. Know the scope: no USB in this tutorial</h3>
<p>The PIC18F4550 is famous for its USB peripheral, so be precise about expectations: the official PICSimLab documentation for these boards describes the chip and the MPLAB X/XC8 example flow, and does <strong>not</strong> document USB simulation for it. This tutorial therefore covers the core digital I/O workflow only. If your goal is a real USB device, plan to develop and test that part on physical hardware; use PICSimLab for the surrounding logic (buttons, displays, ADC, serial-style state machines) where simulation genuinely helps.</p>
<h2>Example code (XC8, PIC18F4550)</h2>
<pre><code>// Example: first PIC18F4550 project, blink on RB0 - XC8
#pragma config FOSC = HS        // High-speed oscillator (example)
#pragma config WDT = OFF        // Watchdog off
#pragma config PBADEN = OFF     // PORTB pins digital on reset
#pragma config MCLRE = ON       // MCLR enabled
#pragma config LVP = OFF        // Low-voltage programming off
#pragma config XINST = OFF      // Extended instruction set off

#include &lt;xc.h&gt;
#define _XTAL_FREQ 20000000     // Example: match the board clock

void main(void) {
    ADCON1 = 0x0F;              // all analog pins digital
    TRISBbits.TRISB0 = 0;       // RB0 output
    LATBbits.LATB0 = 0;         // LED off (write via LATB on PIC18)
    while (1) {
        LATBbits.LATB0 = 1;
        __delay_ms(500);
        LATBbits.LATB0 = 0;
        __delay_ms(500);
    }
}</code></pre>
<h2>Try next</h2>
<ul>
<li><a href="https://picsimlab.com/pic16f877a-blink-led-picsimlab/">PIC16F877A blink</a> — compare the same project across the two families.</li>
<li><a href="https://picsimlab.com/pic16f877a-lcd-hd44780-picsimlab/">HD44780 LCD</a> — port the LCD driver to LAT registers on the 4550.</li>
<li><a href="https://picsimlab.com/pic16f877a-uart-serial-picsimlab/">UART serial</a> — the 4550 USART follows the same pattern as the 877A.</li>
</ul>
<h2>Troubleshooting</h2>
<p><strong>The project builds for the wrong chip.</strong> The device selected in MPLAB X must be PIC18F4550 and the hex must be loaded after selecting the PIC18F4550 on the board in PICSimLab. A PIC16F877A hex will not run correctly on the 4550 configuration.</p>
<p><strong>RB0 does nothing.</strong> Check the two PIC18 traps first: pins left as analog inputs (fix with ADCON1/PBADEN as in the example) and output writes done to PORTB instead of LATB.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
