<?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>gprs Archives | Microcontroller Tutorials</title>
	<atom:link href="https://www.teachmemicro.com/tag/gprs/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.teachmemicro.com/tag/gprs/</link>
	<description>Microcontroller Tutorials and Resources</description>
	<lastBuildDate>Sat, 11 Oct 2025 06:14:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0.2</generator>

<image>
	<url>https://www.teachmemicro.com/wp-content/uploads/2019/04/blue-icon-65x65.png</url>
	<title>gprs Archives | Microcontroller Tutorials</title>
	<link>https://www.teachmemicro.com/tag/gprs/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Using SIM800L with Arduino</title>
		<link>https://www.teachmemicro.com/arduino-sim800l-tutorial/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=arduino-sim800l-tutorial</link>
					<comments>https://www.teachmemicro.com/arduino-sim800l-tutorial/#comments</comments>
		
		<dc:creator><![CDATA[Roland Pelayo]]></dc:creator>
		<pubDate>Fri, 11 Aug 2017 06:32:28 +0000</pubDate>
				<category><![CDATA[Arduino Tutorial]]></category>
		<category><![CDATA[breakout board]]></category>
		<category><![CDATA[gprs]]></category>
		<category><![CDATA[gsm]]></category>
		<category><![CDATA[sim800]]></category>
		<guid isPermaLink="false">https://www.teachmemicro.com/?p=907</guid>

					<description><![CDATA[<p>The SIM800L is a small, low-cost GSM/GPRS module (2G) with most of the features of larger SIM900 shields. In this Arduino SIM800L tutorial, you’ll wire the module safely, send/receive SMS, and make HTTP requests over GPRS — plus fix the most common power and network issues. Video Tutorial What is SIM800L? SIM800L is a quad-band &#8230;</p>
<p>The post <a href="https://www.teachmemicro.com/arduino-sim800l-tutorial/">Using SIM800L with Arduino</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><strong data-start="588" data-end="603">The <a href="https://www.win-source.net/products/detail/simcom/sim800l.html">SIM800L</a></strong> is a small, low-cost GSM/GPRS module (2G) with most of the features of larger SIM900 shields. In this <strong data-start="706" data-end="734">Arduino SIM800L tutorial</strong>, you’ll wire the module safely, send/receive <strong data-start="780" data-end="787">SMS</strong>, and make <strong data-start="798" data-end="806">HTTP</strong> requests over <strong data-start="821" data-end="829">GPRS</strong> — plus fix the most common power and network issues.</p>
<p><span id="more-907"></span></p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-911 size-medium" src="https://www.teachmemicro.com/wp-content/uploads/2017/08/arduino-sim800L-pins-300x300.jpg" alt="Arduino sim800L breakout board" width="300" height="300" srcset="https://www.teachmemicro.com/wp-content/uploads/2017/08/arduino-sim800L-pins-300x300.jpg 300w, https://www.teachmemicro.com/wp-content/uploads/2017/08/arduino-sim800L-pins-150x150.jpg 150w, https://www.teachmemicro.com/wp-content/uploads/2017/08/arduino-sim800L-pins-65x65.jpg 65w, https://www.teachmemicro.com/wp-content/uploads/2017/08/arduino-sim800L-pins.jpg 700w" sizes="auto, (max-width: 300px) 100vw, 300px" /></p>
<h3>Video Tutorial</h3>
<p><iframe loading="lazy" width="560" height="315" src="https://www.youtube.com/embed/Iava4bdIhUg" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="allowfullscreen"></iframe></p>
<hr />
<h3><strong>What is SIM800L?</strong></h3>
<ul>
<li>SIM800L is a quad-band GSM/GPRS module (850/900/1800/1900 MHz) that supports:</li>
<li>Voice calls (speaker/mic pins)</li>
<li>SMS send/receive</li>
<li>GPRS data (HTTP/TCP/UDP)</li>
<li>FM radio</li>
<li>AT commands (UART)</li>
</ul>
<ul></ul>
<p>Read more information from the <a href="https://www.e-gizmo.net/oc/kits%20documents/SIM800L%20module/SIM800L%20module.pdf">SIM800L Datasheet</a>.</p>
<p><img loading="lazy" decoding="async" class="size-large wp-image-1867 aligncenter" src="https://www.teachmemicro.com/wp-content/uploads/2017/08/sim800l-pinout-1024x364.jpg" alt="SIM800L Pinout" width="618" height="220" srcset="https://www.teachmemicro.com/wp-content/uploads/2017/08/sim800l-pinout-1024x364.jpg 1024w, https://www.teachmemicro.com/wp-content/uploads/2017/08/sim800l-pinout-300x107.jpg 300w, https://www.teachmemicro.com/wp-content/uploads/2017/08/sim800l-pinout-768x273.jpg 768w, https://www.teachmemicro.com/wp-content/uploads/2017/08/sim800l-pinout-24x9.jpg 24w, https://www.teachmemicro.com/wp-content/uploads/2017/08/sim800l-pinout-36x13.jpg 36w, https://www.teachmemicro.com/wp-content/uploads/2017/08/sim800l-pinout-48x17.jpg 48w, https://www.teachmemicro.com/wp-content/uploads/2017/08/sim800l-pinout.jpg 1808w" sizes="auto, (max-width: 618px) 100vw, 618px" /></p>
<p><em>If you own a SIM900 shield instead, see: <a href="https://www.teachmemicro.com/sim900a-arduino/">SIM900 Tutorial</a></em></p>
<hr />
<h3><strong>Powering the Board<br />
</strong></h3>
<ul>
<li><strong>Voltage:</strong> 3.7–4.2 V (typical 4.0 V). Do not power from Arduino 5 V or 3.3 V pins.</li>
<li><strong>Current:</strong> Up to 2 A bursts during transmit. Your supply must handle this.</li>
<li><strong>Recommended supplies:</strong>
<ul>
<li><strong>1-cell Li-Po</strong> (3.7 V nominal) <strong>OR</strong></li>
<li>A buck regulator module (e.g. LM2596S) set to ~4.0 V.</li>
</ul>
</li>
<li><strong>Decoupling:</strong> Place 100 µF + 1000 µF low-ESR capacitors near the module Vcc/GND.</li>
<li><strong>Wiring:</strong> Keep power leads short and thick; share common GND with Arduino.</li>
</ul>
<p>Power requirements is probably the most common issue with the SIM800L. This board draws a maximum of <strong>2 A</strong> with an input voltage of <strong>3.7 V to 4.2 V</strong>. This means you <em>must not</em> connect its pins directly to a 5 V Arduino! It doesn't even run on 3.3 V. However, its <em>TX and RX pins are 5V tolerant</em>.</p>
<p>Some YouTube videos power their modules from the Arduino UNO's power pins which really doesn't work for me. When on USB port, the Arduino's 5V pin can supply a <em>maximum of 450 mA</em> and when on its DC Jack, <em>about 800 mA</em>. However, these might explain why their modules work:</p>
<ul>
<li>their Arduino's have internal regulators that drop the voltage to ~4.4-4.5 V when the SIM800L is connected</li>
<li>they are very close to mobile network transmitters, which means the SIM800L doesn't need to draw too much power to establish a connection</li>
</ul>
<p>Some also use a diode to drop the 5 V voltage to ~4.3 V (assuming a silicon diode). Maybe this would solve the voltage problem, but not the current problem.</p>
<p>The better approach is either to use a <strong>regulator</strong> or just have the SIM800L <strong>draw from a Li-Po battery</strong>.</p>
<p>If selecting a voltage regulator, I recommend the <a href="https://www.circuitxcode.com/lm2596s-module-tutorial/">LM2596S regulator</a> module.</p>
<p><img loading="lazy" decoding="async" class="aligncenter" src="https://lh6.googleusercontent.com/jLorGOPM46YAO7TDhocbO8swsSPvJIvHPuhqB9Pe5dmgy26uWw7nrscLCIPb9PwpDVj4C--EbSpsJsQgaWWQIu6R3MmCsjIP1zjk4yapFr224EzbbgcPM5QGPdLUS-I7L64MhUXY" width="532" height="532" /></p>
<p id="vgGczlM">The LM2596S can provide a maximum 3 A to its load. You simply use a higher voltage in its input then <em>adjust the on-board potentiometer</em> to have 3.7 to 4.4 V for the SIM800L. Take note that the <em>input voltage must be at least 1.5 V higher</em> than the output.</p>
<p><a href="https://www.teachmemicro.com/wp-content/uploads/2017/08/arduino-sim800l-lm2596.avif"><img data-dominant-color="a8abb0" data-has-transparency="false" style="--dominant-color: #a8abb0;" loading="lazy" decoding="async" src="https://www.teachmemicro.com/wp-content/uploads/2017/08/arduino-sim800l-lm2596-1024x295.avif" alt="Arduino SIM800L with LM2596" width="618" height="178" class="aligncenter size-large wp-image-9497 not-transparent" srcset="https://www.teachmemicro.com/wp-content/uploads/2017/08/arduino-sim800l-lm2596-1024x295.avif 1024w, https://www.teachmemicro.com/wp-content/uploads/2017/08/arduino-sim800l-lm2596-300x86.avif 300w, https://www.teachmemicro.com/wp-content/uploads/2017/08/arduino-sim800l-lm2596-768x221.avif 768w, https://www.teachmemicro.com/wp-content/uploads/2017/08/arduino-sim800l-lm2596.avif 1293w" sizes="auto, (max-width: 618px) 100vw, 618px" /></a></p>
<p>A Li-Po battery works well too, since they provide 3.7 V. I recommend Li-Po battery with higher ampere-hour ratings so that it can provide the SIM800L's current requirements. My <a href="https://www.teachmemicro.com/sim800-network-test-troubleshoot/">network test project</a> uses a battery to supply power to the SIM800L.<br />
<a href="https://www.teachmemicro.com/wp-content/uploads/2017/08/arduino-sim800l-lipo-battery.avif"><img data-dominant-color="e2d7c9" data-has-transparency="false" style="--dominant-color: #e2d7c9;" loading="lazy" decoding="async" src="https://www.teachmemicro.com/wp-content/uploads/2017/08/arduino-sim800l-lipo-battery-1024x660.avif" alt="Arduino SIM800L LiPo Battery" width="618" height="398" class="aligncenter size-large wp-image-9498 not-transparent" srcset="https://www.teachmemicro.com/wp-content/uploads/2017/08/arduino-sim800l-lipo-battery-1024x660.avif 1024w, https://www.teachmemicro.com/wp-content/uploads/2017/08/arduino-sim800l-lipo-battery-300x193.avif 300w, https://www.teachmemicro.com/wp-content/uploads/2017/08/arduino-sim800l-lipo-battery-768x495.avif 768w, https://www.teachmemicro.com/wp-content/uploads/2017/08/arduino-sim800l-lipo-battery.avif 1107w" sizes="auto, (max-width: 618px) 100vw, 618px" /></a></p>
<p>&nbsp;</p>
<hr />
<h3><strong>Wiring &amp; Level Shifting</strong></h3>
<p>SIM800L’s UART is 3.3 V tolerant on RXD; many boards survive 5 V UART, but safest is level shifting from Arduino TX → SIM800L RXD.</p>
<p>Typical connections (Arduino UNO):</p>
<table data-start="3001" data-end="3439" class="w-fit min-w-(--thread-content-width)">
<thead data-start="3001" data-end="3036">
<tr data-start="3001" data-end="3036">
<th data-start="3001" data-end="3011" data-col-size="sm">SIM800L</th>
<th data-start="3011" data-end="3025" data-col-size="sm">Description</th>
<th data-start="3025" data-end="3036" data-col-size="md">Arduino</th>
</tr>
</thead>
<tbody data-start="3051" data-end="3439">
<tr data-start="3051" data-end="3122">
<td data-start="3051" data-end="3057" data-col-size="sm">Vcc</td>
<td data-start="3057" data-end="3089" data-col-size="sm">3.7–4.2 V supply (cap nearby)</td>
<td data-start="3089" data-end="3122" data-col-size="md">External supply (NOT 5 V pin)</td>
</tr>
<tr data-start="3123" data-end="3167">
<td data-start="3123" data-end="3129" data-col-size="sm">GND</td>
<td data-start="3129" data-end="3138" data-col-size="sm">Ground</td>
<td data-start="3138" data-end="3167" data-col-size="md">GND (common with Arduino)</td>
</tr>
<tr data-start="3168" data-end="3241">
<td data-start="3168" data-end="3174" data-col-size="sm">TXD</td>
<td data-start="3174" data-end="3187" data-col-size="sm">SIM800L TX</td>
<td data-start="3187" data-end="3241" data-col-size="md">Arduino <strong data-start="3197" data-end="3203">RX</strong> (e.g., D3)</td>
</tr>
<tr data-start="3242" data-end="3309">
<td data-start="3242" data-end="3248" data-col-size="sm">RXD</td>
<td data-start="3248" data-end="3261" data-col-size="sm">SIM800L RX</td>
<td data-start="3261" data-end="3309" data-col-size="md">Arduino <strong data-start="3271" data-end="3277">TX</strong> via level shifter (e.g., D4)</td>
</tr>
<tr data-start="3310" data-end="3361">
<td data-start="3310" data-end="3316" data-col-size="sm">RST</td>
<td data-start="3316" data-end="3335" data-col-size="sm">Reset (optional)</td>
<td data-start="3335" data-end="3361" data-col-size="md">Any digital (e.g., D5)</td>
</tr>
<tr data-start="3362" data-end="3439">
<td data-start="3362" data-end="3369" data-col-size="sm">RING</td>
<td data-start="3369" data-end="3397" data-col-size="sm">Ring indicator (optional)</td>
<td data-start="3397" data-end="3439" data-col-size="md">D2 if using interrupt on incoming call</td>
</tr>
</tbody>
</table>
<p><strong>Baud:</strong> 9600 is safe for SoftwareSerial. For boards with extra hardware UART (Mega/Leonardo/ESP32), prefer hardware serial.</p>
<p><a href="https://www.teachmemicro.com/wp-content/uploads/2017/08/arduino-sim800l-wiring-diagram-lipo.avif"><img data-dominant-color="c7cdca" data-has-transparency="false" style="--dominant-color: #c7cdca;" loading="lazy" decoding="async" src="https://www.teachmemicro.com/wp-content/uploads/2017/08/arduino-sim800l-wiring-diagram-lipo-1024x520.avif" alt="Arduino and SIM800L Wiring Diagram" width="618" height="314" class="aligncenter size-large wp-image-9501 not-transparent" srcset="https://www.teachmemicro.com/wp-content/uploads/2017/08/arduino-sim800l-wiring-diagram-lipo-1024x520.avif 1024w, https://www.teachmemicro.com/wp-content/uploads/2017/08/arduino-sim800l-wiring-diagram-lipo-300x152.avif 300w, https://www.teachmemicro.com/wp-content/uploads/2017/08/arduino-sim800l-wiring-diagram-lipo-768x390.avif 768w, https://www.teachmemicro.com/wp-content/uploads/2017/08/arduino-sim800l-wiring-diagram-lipo.avif 1218w" sizes="auto, (max-width: 618px) 100vw, 618px" /></a></p>
<p>&nbsp;</p>
<hr />
<h3><strong>Connecting the SIM800L to Network</strong></h3>
<p>If the power to the SIM800L is enough, the on-board LED starts blinking. If there's not enough power, the LED blinks  for about three seconds, then turns off.</p>
<p>The frequency of the blinking means something:</p>
<p><strong>Blink every 1s:</strong> searching for network</p>
<p><a href="https://www.teachmemicro.com/wp-content/uploads/2017/08/SIM800L_LED_1s.gif"><img data-dominant-color="d1907f" data-has-transparency="true" style="--dominant-color: #d1907f;" loading="lazy" decoding="async" src="https://www.teachmemicro.com/wp-content/uploads/2017/08/SIM800L_LED_1s.gif" alt="SIM800 - Looking for network
" width="169" height="170" class="wp-image-9502  alignleft has-transparency" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><strong>Blink every 3s:</strong> registered on network</p>
<p><a href="https://www.teachmemicro.com/wp-content/uploads/2017/08/SIM800L_LED_3s.gif"><img data-dominant-color="d1907f" data-has-transparency="true" style="--dominant-color: #d1907f;" loading="lazy" decoding="async" src="https://www.teachmemicro.com/wp-content/uploads/2017/08/SIM800L_LED_3s.gif" alt="SIM800 -  Connected to network" width="169" height="170" class="wp-image-9504  alignleft has-transparency" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><strong>Blink ~2×/s:</strong> GPRS active</p>
<p><a href="https://www.teachmemicro.com/wp-content/uploads/2017/08/SIM800L_LED_2s.gif"><img data-dominant-color="d1907f" data-has-transparency="true" style="--dominant-color: #d1907f;" loading="lazy" decoding="async" src="https://www.teachmemicro.com/wp-content/uploads/2017/08/SIM800L_LED_2s.gif" alt="SIM800 - Looking for network
" width="169" height="170" class="wp-image-9503  alignleft has-transparency" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Here's a video showing these LED indications:</p>
<p><iframe loading="lazy" width="560" height="315" src="https://www.youtube.com/embed/Q9E6e1QPyYk" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="allowfullscreen"></iframe></p>
<p>Antennas are essential for this kind of module <em>especially</em> if your project is indoors. Without an antenna, there would not be enough transmitting power for the SIM800L to perform GSM services such as calls and SMS.</p>
<p style="text-align: center;"><a href="http://s.click.aliexpress.com/e/6qBYvRZ" target="_parent" rel="noopener noreferrer"><img decoding="async" class="aligncenter" src="//ae01.alicdn.com/kf/HTB1uhvNSFXXXXcxXXXXq6xXFXXXL/-font-b-Antenna-b-font-for-font-b-SIM800L-b-font-GPRS-TCP-IP-module.jpg_220x220.jpg" /><span style="display: block;">SIM800L Antenna</span></a></p>
<p>The image above is an <em>outdoor whip antenna</em> and I found this antenna to be more effective than the <em>indoor helical antenna </em>that comes with the SIM800L module:</p>
<p><a href="http://s.click.aliexpress.com/e/2faemIE" target="_parent" rel="noopener noreferrer"><img decoding="async" class="aligncenter" src="//ae01.alicdn.com/kf/HTB1d0G1LXXXXXcHXXXXq6xXFXXXL/Smallest-font-b-SIM800L-b-font-GPRS-GSM-Module-Micro-SIM-Card-Core-BOard-Quad-band.jpg_220x220.jpg" /></a></p>
<p>Another type of antenna is the PCB antenna:</p>
<p><a href="https://www.teachmemicro.com/wp-content/uploads/2017/08/pcb-antenna.jpg"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-4479" src="https://www.teachmemicro.com/wp-content/uploads/2017/08/pcb-antenna.jpg" alt="SIM800L PCB antenna" width="496" height="225" srcset="https://www.teachmemicro.com/wp-content/uploads/2017/08/pcb-antenna.jpg 496w, https://www.teachmemicro.com/wp-content/uploads/2017/08/pcb-antenna-300x136.jpg 300w" sizes="auto, (max-width: 496px) 100vw, 496px" /></a></p>
<p>This type of antenna is cheaper and doesn't take much space as that of the whip antenna. Performance wise, the PCB antenna can be as good as the whip if the design is correct.</p>
<p>My recommendation is to use both the indoor helical antenna and either the whip or PCB antenna.</p>
<p><em>If you are still having trouble with the SIM800L, I suggest you try out my <a href="https://www.teachmemicro.com/sim800-network-test-troubleshoot/">network test project</a>. This helps you test out if the module is really connecting to a network or is getting enough power.</em></p>
<hr />
<p><strong>SIM800L and AT Commands</strong></p>
<p>You can control SIM800L using AT commands over serial. Here are some of the basic commands.<strong><br />
</strong></p>
<table data-start="3994" data-end="4423" class="w-fit min-w-(--thread-content-width)">
<thead data-start="3994" data-end="4032">
<tr data-start="3994" data-end="4032">
<th data-start="3994" data-end="4004" data-col-size="sm">Command</th>
<th data-start="4004" data-end="4014" data-col-size="sm">Purpose</th>
<th data-start="4014" data-end="4032" data-col-size="sm">Expected Reply</th>
</tr>
</thead>
<tbody data-start="4047" data-end="4423">
<tr data-start="4047" data-end="4074">
<td data-start="4047" data-end="4054" data-col-size="sm">AT</td>
<td data-start="4054" data-end="4066" data-col-size="sm">Handshake</td>
<td data-start="4066" data-end="4074" data-col-size="sm">OK</td>
</tr>
<tr data-start="4075" data-end="4119">
<td data-start="4075" data-end="4088" data-col-size="sm">AT+CPIN?</td>
<td data-start="4088" data-end="4101" data-col-size="sm">SIM ready?</td>
<td data-start="4101" data-end="4119" data-col-size="sm">+CPIN: READY</td>
</tr>
<tr data-start="4120" data-end="4189">
<td data-start="4120" data-end="4131" data-col-size="sm">AT+CSQ</td>
<td data-start="4131" data-end="4148" data-col-size="sm">Signal quality</td>
<td data-start="4148" data-end="4189" data-col-size="sm">+CSQ: &lt;rssi&gt;,&lt;ber&gt; (31 = best RSSI)</td>
</tr>
<tr data-start="4190" data-end="4267">
<td data-start="4190" data-end="4203" data-col-size="sm">AT+CREG?</td>
<td data-start="4203" data-end="4226" data-col-size="sm">Network registration</td>
<td data-start="4226" data-end="4267" data-col-size="sm">+CREG: 1,1 (home) / 1,5 (roaming)</td>
</tr>
<tr data-start="4268" data-end="4314">
<td data-start="4268" data-end="4282" data-col-size="sm">AT+CGATT?</td>
<td data-start="4282" data-end="4299" data-col-size="sm">GPRS attached?</td>
<td data-start="4299" data-end="4314" data-col-size="sm">+CGATT: 1</td>
</tr>
<tr data-start="4315" data-end="4359">
<td data-start="4315" data-end="4328" data-col-size="sm">AT+SAPBR</td>
<td data-start="4328" data-end="4351" data-col-size="sm">Bearer profile (APN)</td>
<td data-start="4351" data-end="4359" data-col-size="sm">OK</td>
</tr>
<tr data-start="4360" data-end="4423">
<td data-start="4360" data-end="4396" data-col-size="sm">AT+HTTPINIT/HTTPPARA/HTTPACTION</td>
<td data-start="4396" data-end="4407" data-col-size="sm">HTTP ops</td>
<td data-start="4407" data-end="4423" data-col-size="sm">status codes</td>
</tr>
</tbody>
</table>
<p>The Arduino sends these commands <a href="https://www.teachmemicro.com/microcontroller-serial-communication/"><em>serially</em></a> to the SIM800L, and the latter replies via the same serial port.</p>
<p>The first command is the initial handshake command, which is simply:</p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-bash" data-lang="Bash"><pre><code class="language-cpp">AT</code></pre></pre>
</div>
<p>If the SIM800L is good to go, it should reply with:</p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-bash" data-lang="Bash"><pre><code class="language-cpp">OK</code></pre></pre>
</div>
<p>Other commands we can use to check the SIM800L is the signal quality test:</p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-bash" data-lang="Bash"><pre><code class="language-cpp">AT+CSQ</code></pre></pre>
</div>
<p>for which the module should reply something like this:</p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-bash" data-lang="Bash"><pre><code class="language-cpp">+CSQ:18,99</code></pre></pre>
</div>
<p>The first number is the Received Signal Strength Indicator (RSSI) which tells you about the network signal the module is receiving. A good RSSI is 31:</p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-bash" data-lang="Bash"><pre><code class="language-cpp">0 -&gt; -113 dBm or less 
1 -&gt; -111 dBm 
2...30 -&gt; -109...-53 dBm 
31 -&gt; -51 dBm or greater 
99 -&gt; not known or not detectable</code></pre></pre>
</div>
<p>The second number is the Bit Error Rate (BER) which is the number of bit errors divided by the total number of bits received by the module. Possible values are 0 to 7 or 99:</p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-bash" data-lang="Bash"><pre><code class="language-cpp">0 -&gt; BER &lt; 0.2% 
1 -&gt; 0.2% &lt; BER &lt; 0.4% 
2 -&gt; 0.4% &lt; BER &lt; 0.8% 
3 -&gt; 0.8% &lt; BER &lt; 1.6% 
4 -&gt; 1.6% &lt; BER &lt; 3.2 % 
5 -&gt; 3.2% &lt; BER &lt; 6.4% 
6 -&gt; 6.4% &lt; BER &lt; 12.8% 
7 -&gt; 12.8% &lt; BER 99 -&gt; not known or not detectable</code></pre></pre>
</div>
<p>The higher the BER, the more bit errors. Thus, the ideal BER value should be closer to 0.</p>
<p>The network registration test can tell you if the SIM800L is ready to send/receive SMS or make calls:</p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-bash" data-lang="Bash"><pre><code class="language-cpp">AT+CREG?</code></pre></pre>
</div>
<p>The module will reply with two numbers:</p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-bash" data-lang="Bash"><pre><code class="language-cpp">+CREG: 1,1</code></pre></pre>
</div>
<p>Where the 1st number is:</p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-bash" data-lang="Bash"><pre><code class="language-cpp">0 not registered, MT is not currently searching a new operator to register to 
1 registered, home network 
2 not registered, but MT is currently searching a new operator to register to 
3 registration denied 
4 unknown (e.g. out of GERAN/UTRAN/E-UTRAN coverage) 
5 registered, roaming 
6 registered for &quot;SMS only&quot;, home network (applicable only when indicates E-UTRAN) 
7 registered for &quot;SMS only&quot;, roaming (applicable only when indicates E-UTRAN) 
8 attached for emergency bearer services only (see NOTE 2) (not applicable) 
9 registered for &quot;CSFB not preferred&quot;, home network (applicable only when indicates E-UTRAN) 
10 registered for &quot;CSFB not preferred&quot;, roaming (applicable only when indicates E-UTRAN)</code></pre></pre>
</div>
<p>and the second number is:</p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-bash" data-lang="Bash"><pre><code class="language-cpp">0 GSM 
1 GSM Compact 
2 UTRAN 
3 GSM w/EGPRS 
4 UTRAN w/HSDPA 
5 UTRAN w/HSUPA 
6 UTRAN w/HSDPA and HSUPA 
7 E-UTRAN</code></pre></pre>
</div>
<p>The ideal reply from a SIM800L to function well (including data) is:</p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-bash" data-lang="Bash"><pre><code class="language-cpp">+CREG: 1,3 
+CREG: 1,4 
+CREG: 1,5 
+CREG: 1,6</code></pre></pre>
</div>
<p>Note that results may vary with your location.</p>
<p>The Arduino UNO has a hardware serial port but it's the one used for sending code to it via USB. Instead, we use a serial port emulated through software. For this example, use the provided wiring diagram in the previous section.</p>
<p>First we include the library and then create a <em>Software Serial</em> object:</p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">#include &lt;SoftwareSerial.h&gt; 

SoftwareSerial sim800l(3, 2);</code></pre></pre>
</div>
<p>We need to know the reply of the SIM800L. So we initialize both hardware and serial ports in order to print the replies via serial monitor:</p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">Serial.begin(9600); 
sim800l.begin(9600);</code></pre></pre>
</div>
<p>To send a command, we do:</p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">sim800l.println(&quot;AT&quot;);</code></pre></pre>
</div>
<p>Or we can just send the commands via serial monitor. To do that and also read the reply from the SIM800L, we place this inside <em>loop()</em>:</p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">while (Serial.available()){ 
   delay(1); 
   sim800l.write(Serial.read()); 
} 

while (sim800l.available()){ 
   Serial.write(sim800l.read()); 
}</code></pre></pre>
</div>
<p>Here is the full sketch for the AT command test:</p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">#include &lt;SoftwareSerial.h&gt; 

SoftwareSerial sim800l(3,2); 

void setup(){ 
  Serial.begin(9600); 
  sim800l.begin(9600); 
} 

void loop(){ 
  while (Serial.available()){ 
    delay(1); 
    sim800l.write(Serial.read());
  } 

  while (sim800l.available()){ 
    Serial.write(sim800l.read()); 
  } 
}</code></pre></pre>
</div>
<p>Open Serial Monitor @ 9600, type <em>AT</em>, expect OK. Then try <em>AT+CSQ</em>, <em>AT+CREG?</em>.</p>
<p>Here's how the SIM800L is responding with AT Commands:</p>
<p><video width="300" height="150" style="width: 308px; height: 308px;" preload="auto" autoplay="autoplay" loop="loop"><source src="https://i.imgur.com/e7TVE6y.mp4" type="video/mp4" /></video></p>
<hr />
<h3><strong>The FONA Library</strong></h3>
<p>While we can maximize the functions of the SIM800l through AT commands, it is much easier to use an existing library instead. The library I recommend is <strong><em>Adafruit's FONA library</em></strong>. Download it <a href="https://github.com/adafruit/Adafruit_FONA">here</a> and extract it on <em>Documents &gt; Arduino &gt; libraries. </em>Or you can go to <em>Sketch &gt; Include Library &gt; Manage Libraries </em>and type "FONA" in the search bar.</p>
<p id="SVPcBMo"><img loading="lazy" decoding="async" width="782" height="437" class="alignnone size-full wp-image-4480 " src="https://www.teachmemicro.com/wp-content/uploads/2020/06/img_5ee3045f3d12a.png" alt="" srcset="https://www.teachmemicro.com/wp-content/uploads/2020/06/img_5ee3045f3d12a.png 782w, https://www.teachmemicro.com/wp-content/uploads/2020/06/img_5ee3045f3d12a-300x168.png 300w, https://www.teachmemicro.com/wp-content/uploads/2020/06/img_5ee3045f3d12a-768x429.png 768w" sizes="auto, (max-width: 782px) 100vw, 782px" /></p>
<p>The library comes with a number of examples. The FONA_test sketch gives us access to all the SIM800l functions! If you upload the sketch and use the same wiring diagram, you'll see this on the serial monitor:</p>
<p><a href="https://www.teachmemicro.com/wp-content/uploads/2017/08/fona-test-menu.jpg"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-4481" src="https://www.teachmemicro.com/wp-content/uploads/2017/08/fona-test-menu.jpg" alt="" width="523" height="727" srcset="https://www.teachmemicro.com/wp-content/uploads/2017/08/fona-test-menu.jpg 523w, https://www.teachmemicro.com/wp-content/uploads/2017/08/fona-test-menu-216x300.jpg 216w" sizes="auto, (max-width: 523px) 100vw, 523px" /></a></p>
<p>Here's a short video showing how I sent an SMS using this library:</p>
<p><iframe loading="lazy" width="560" height="315" src="https://www.youtube.com/embed/Lqgb59zdx-o" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="allowfullscreen"></iframe></p>
<hr />
<h3><strong>SMS Sending</strong></h3>
<p>The FONA library has a simple <em>sendSMS()</em> function that accepts the number and message as parameters and returns true if the message was sent through the network successfully. Here's an example code that sends one SMS:</p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">#include &lt;SoftwareSerial.h&gt;
#include &quot;Adafruit_FONA.h&quot;

#define FONA_RX 2
#define FONA_TX 3
#define FONA_RST 4

char replybuffer[255];

SoftwareSerial sim800l = SoftwareSerial(FONA_TX, FONA_RX);

Adafruit_FONA gsm = Adafruit_FONA(FONA_RST);

//uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);

void setup() {
  Serial.begin(9600);
  sim800l.begin(9600); 
  if (! gsm.begin(sim800l)) {            
    Serial.println(F(&quot;Couldn&#039;t find SIM800L!&quot;));
    while (1);
  }
  
   char sendto[21] = &quot;09173234058&quot;;
   char message[141] = &quot;Hello from SIM800L&quot;;
   gsm.sendSMS(sendto, message);
   delay(1000);
}

void loop() {}</code></pre></pre>
</div>
<p>Upload this sketch to your Arduino and open serial monitor to send SMS.</p>
<p>Let me explain the sketch above. Let's start with this:</p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">#define FONA_RX 2
#define FONA_TX 3
#define FONA_RST 4</code></pre></pre>
<p>This part declares that the RX, TX and RST pins of the SIM800L must be connected to pin 2, 3 and 4 of the Arduino.</p>
<pre class="lang:arduino decode:true">SoftwareSerial sim800l = SoftwareSerial(FONA_TX, FONA_RX);

Adafruit_FONA gsm = Adafruit_FONA(FONA_RST);

</pre>
</div>
<p>The lines above assigns the RX and TX pins as <em>software serial</em> pins. This is done so that the Arduino's hardware serial port remains to be used with the serial monitor. The FONA object (<em>gsm</em>) is then initialized with the RST pin as parameter.</p>
<h4><em>Check out my <a href="https://www.teachmemicro.com/arduino-gprs">GPRS tutorial </a>to learn how to use the SIM800 module to connect to the Internet</em></h4>
<p>The SIM800L is checked using the following sequence:</p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">if (! gsm.begin(sim800l)) { 
   Serial.println(F(&quot;Couldn&#039;t find SIM800L!&quot;)); 
   while (1); 
}</code></pre></pre>
</div>
<p>If "Couldn't find SIM800L!" appears in the serial monitor the program goes to an infinite loop and therefore will not continue.</p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">char sendto[21] = &quot;09171234567&quot;;
char message[141] = &quot;Hello from SIM800L&quot;;
gsm.sendSMS(sendto, message);
delay(1000);</code></pre></pre>
</div>
<p>This part is the SMS sending part. The message "Hello from SIM800L" will be sent to the number  "09171234567" when the Arduino starts.</p>
<hr />
<h3><strong>Reading SMS</strong></h3>
<p>How about sending SMS to the SIM800L and reading it? We add a function for reading SMS:</p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">void readSMS(int smsn){
          uint16_t smslen;
          if (! gsm.getSMSSender(smsn, replybuffer, 250)) {
            Serial.println(&quot;Failed!&quot;);
            return;
          }
          Serial.print(F(&quot;FROM: &quot;)); 
          Serial.println(replybuffer);
          
          Serial.print(F(&quot;\n\rReading SMS #&quot;)); Serial.println(smsn);
          if (!gsm.readSMS(smsn, replybuffer, 250, &amp;smslen)) {  // pass in buffer and max len!
            Serial.println(F(&quot;Failed!&quot;));
            return;
          }
          Serial.println(replybuffer);
}</code></pre></pre>
</div>
<p>The function <em>getSMSSender()</em> returns true and places the SMS sender number to the <em>replybuffer, </em>while the <em>readSMS()</em> function returns true and places the SMS to that same buffer.</p>
<p>To use the function, specify which SMS you want to read:</p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">readSMS(1);</code></pre></pre>
</div>
<p>This code reads the SMS at location #1. The disadvantage of this code is you can't read the <em>latest SMS</em> because they are not indexed according to delivery time.  If your applications requires to read the latest SMS, I suggest you use the <a href="https://github.com/adafruit/Adafruit_FONA/tree/master/examples/FONA_SMS_Response"><em>FONA_SMS_response</em></a> example sketch from the FONA library.</p>
<hr />
<h3><strong>Making a Call</strong></h3>
<p>To make a call, we must attached a speaker to the SPKRP and SPRKRN terminals of the SIM800L and an electret microphone to the MICP and MICN terminals.</p>
<p>&nbsp;</p>
<p><a href="https://www.teachmemicro.com/wp-content/uploads/2017/08/arduino-sim800l-speaker-microphone-calling-1.avif"><img data-dominant-color="cbcecc" data-has-transparency="false" style="--dominant-color: #cbcecc;" loading="lazy" decoding="async" src="https://www.teachmemicro.com/wp-content/uploads/2017/08/arduino-sim800l-speaker-microphone-calling-1-1024x721.avif" alt="Arduino SIM800L with Speaker and Microphone for Calling" width="618" height="435" class="aligncenter size-large wp-image-9500 not-transparent" srcset="https://www.teachmemicro.com/wp-content/uploads/2017/08/arduino-sim800l-speaker-microphone-calling-1-1024x721.avif 1024w, https://www.teachmemicro.com/wp-content/uploads/2017/08/arduino-sim800l-speaker-microphone-calling-1-300x211.avif 300w, https://www.teachmemicro.com/wp-content/uploads/2017/08/arduino-sim800l-speaker-microphone-calling-1-768x541.avif 768w, https://www.teachmemicro.com/wp-content/uploads/2017/08/arduino-sim800l-speaker-microphone-calling-1.avif 1139w" sizes="auto, (max-width: 618px) 100vw, 618px" /></a></p>
<p>Then we add another function:</p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">void callNumber(char * number){
   if (!gsm.callPhone(number)) {
       Serial.println(F(&quot;Failed&quot;));
   } else {
       Serial.println(F(&quot;Sent!&quot;));
   }
}</code></pre></pre>
</div>
<p>Calling a number is possible through the <em>callPhone()</em> function from the library. Moreover, this function <em>returns true</em> if the call is successfull. The number to be called is the parameter for this function.</p>
<p>To use this function, just pass the number to be called like this:</p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">char callNum[21] = &quot;09171234567&quot;;
callNumber(callNum);</code></pre></pre>
</div>
<hr />
<h3><strong>Receiving a Call</strong></h3>
<p>Receiving a call is a bit more complicated because there must be an interrupt trigger to acknowledge the call. This is what the example <em>IncomingCall</em> sketch does:</p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">#include &lt;SoftwareSerial.h&gt;
#include &quot;Adafruit_FONA.h&quot;

#define FONA_RX            3
#define FONA_TX            4
#define FONA_RST           5

#define FONA_RI_INTERRUPT  0
                             
SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);

Adafruit_FONA fona = Adafruit_FONA(FONA_RST);

void setup() {
  Serial.begin(115200);
  Serial.println(F(&quot;FONA incoming call example&quot;));
  Serial.println(F(&quot;Initializing....(May take 3 seconds)&quot;));
  fonaSS.begin(4800); // if you&#039;re using software serial
  if (! fona.begin(fonaSS)) {           // can also try fona.begin(Serial1) 
    Serial.println(F(&quot;Couldn&#039;t find FONA&quot;));
    while (1);
  }
  Serial.println(F(&quot;FONA is OK&quot;));

  if(fona.callerIdNotification(true, FONA_RI_INTERRUPT)) {
    Serial.println(F(&quot;Caller id notification enabled.&quot;));
  }
  else {
    Serial.println(F(&quot;Caller id notification disabled&quot;));
  }
}

void loop(){
  char phone[32] = {0};
  if(fona.incomingCallNumber(phone)){
    Serial.println(F(&quot;RING!&quot;));
    Serial.print(F(&quot;Phone Number: &quot;));
    Serial.println(phone);
  }
}</code></pre></pre>
</div>
<p>The first thing that is noticeable is the change in the pin assignments for RX, TX and RST. This is because the D2 pin of the Arduino is the default interrupt pin. The SIM800L uses this pin to interrupt the Arduino whenever there is an incoming call. Thus, connecting the D2 pin to the SIM800L's RING pin (above the DTR pin, if its not visible in yours) is a must.</p>
<p>There's also an option to enable or disable Caller ID notification. Cool.</p>
<hr />
<h3><strong>HTTP over GPRS (GET example)</strong></h3>
<p>Below shows a minimal HTTP GET using AT commands via a simple helper. Replace <em>your.apn.here</em> with your provider APN and <em>http://example.com/endpoint</em> with your URL.</p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">bool sendAT(Stream&amp; s, const char* cmd, const char* expect, uint16_t to=5000){
  s.println(cmd);
  unsigned long t = millis();
  String resp;
  while (millis() - t &lt; to) { while (s.available()) resp += (char)s.read(); if (resp.indexOf(expect) &gt;= 0) return true;
  }
  Serial.println(resp);
  return false;
}

void httpGet() {
  if (!sendAT(fonaSS, &quot;AT&quot;, &quot;OK&quot;)) return;
  sendAT(fonaSS, &quot;AT+SAPBR=3,1,\&quot;CONTYPE\&quot;,\&quot;GPRS\&quot;&quot;, &quot;OK&quot;);
  sendAT(fonaSS, &quot;AT+SAPBR=3,1,\&quot;APN\&quot;,\&quot;your.apn.here\&quot;&quot;, &quot;OK&quot;);
  sendAT(fonaSS, &quot;AT+SAPBR=1,1&quot;, &quot;OK&quot;);       // open bearer
  sendAT(fonaSS, &quot;AT+HTTPINIT&quot;, &quot;OK&quot;);
  sendAT(fonaSS, &quot;AT+HTTPPARA=\&quot;CID\&quot;,1&quot;, &quot;OK&quot;);
  sendAT(fonaSS, &quot;AT+HTTPPARA=\&quot;URL\&quot;,\&quot;http://example.com/endpoint\&quot;&quot;, &quot;OK&quot;);
  if (sendAT(fonaSS, &quot;AT+HTTPACTION=0&quot;, &quot;HTTPACTION:&quot;)) {
    // After action completes, read body:
    sendAT(fonaSS, &quot;AT+HTTPREAD&quot;, &quot;OK&quot;);
  }
  sendAT(fonaSS, &quot;AT+HTTPTERM&quot;, &quot;OK&quot;);
  sendAT(fonaSS, &quot;AT+SAPBR=0,1&quot;, &quot;OK&quot;);       // close bearer
}</code></pre></pre>
</div>
<p>Prefer FONA’s higher-level HTTP helpers if available in your version. The explicit AT flow above helps with debugging.</p>
<hr />
<h3><strong>Mini Project: Sensor → HTTP Endpoint</strong></h3>
<p>Goal: Read a sensor value (e.g., temperature) and push it to your server every 60 s via HTTP.</p>
<p>Flow:</p>
<ol>
<li>Power up → check SIM, signal (AT+CSQ), and network (AT+CREG?).</li>
<li>Attach GPRS (AT+CGATT=1) and open bearer (AT+SAPBR).</li>
<li>Build URL http://server/upload?temp=XX → HTTPACTION=0.</li>
<li>Parse response; log success/failure; retry with backoff.</li>
</ol>
<h4><strong>Arduino Sketch</strong></h4>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">#include &lt;SoftwareSerial.h&gt;

#define SIM_TX 4   // Arduino → SIM800L RX
#define SIM_RX 3   // Arduino ← SIM800L TX
SoftwareSerial sim800l(SIM_RX, SIM_TX);

void sendAT(const char *cmd, const char *expect, unsigned long timeout = 5000) {
  sim800l.println(cmd);
  unsigned long start = millis();
  String resp = &quot;&quot;;
  while (millis() - start &lt; timeout) { while (sim800l.available()) resp += (char)sim800l.read(); if (resp.indexOf(expect) &gt;= 0) break;
  }
  Serial.println(resp);
}

void setup() {
  Serial.begin(9600);
  sim800l.begin(9600);
  delay(2000);

  Serial.println(&quot;=== SIM800L HTTP POST TEST ===&quot;);

  // 1. Attach to GPRS
  sendAT(&quot;AT&quot;, &quot;OK&quot;);
  sendAT(&quot;AT+CPIN?&quot;, &quot;READY&quot;);
  sendAT(&quot;AT+CGATT=1&quot;, &quot;OK&quot;);
  sendAT(&quot;AT+SAPBR=3,1,\&quot;CONTYPE\&quot;,\&quot;GPRS\&quot;&quot;, &quot;OK&quot;);
  sendAT(&quot;AT+SAPBR=3,1,\&quot;APN\&quot;,\&quot;your.apn.here\&quot;&quot;, &quot;OK&quot;); // &lt;-- replace APN
  sendAT(&quot;AT+SAPBR=1,1&quot;, &quot;OK&quot;);
  sendAT(&quot;AT+SAPBR=2,1&quot;, &quot;SAPBR&quot;);

  // 2. Initialize HTTP
  sendAT(&quot;AT+HTTPINIT&quot;, &quot;OK&quot;);
  sendAT(&quot;AT+HTTPPARA=\&quot;CID\&quot;,1&quot;, &quot;OK&quot;);

  // 3. Set URL (replace with your server URL)
  sendAT(&quot;AT+HTTPPARA=\&quot;URL\&quot;,\&quot;http://example.com/postdata.php\&quot;&quot;, &quot;OK&quot;);

  // 4. Specify content type
  sendAT(&quot;AT+HTTPPARA=\&quot;CONTENT\&quot;,\&quot;application/x-www-form-urlencoded\&quot;&quot;, &quot;OK&quot;);

  // 5. Build POST data (URL-encoded)
  String payload = &quot;temp=26.3&amp;hum=71.2&quot;; // change variables here
  String cmd = &quot;AT+HTTPDATA=&quot; + String(payload.length()) + &quot;,10000&quot;;
  sendAT(cmd.c_str(), &quot;DOWNLOAD&quot;);
  sim800l.print(payload);                // send body
  delay(2000);

  // 6. Start POST
  sendAT(&quot;AT+HTTPACTION=1&quot;, &quot;HTTPACTION:1&quot;);
  delay(5000);

  // 7. Read server response
  sendAT(&quot;AT+HTTPREAD&quot;, &quot;OK&quot;);

  // 8. Close HTTP &amp; bearer
  sendAT(&quot;AT+HTTPTERM&quot;, &quot;OK&quot;);
  sendAT(&quot;AT+SAPBR=0,1&quot;, &quot;OK&quot;);

  Serial.println(&quot;=== POST done ===&quot;);
}

void loop() {}</code></pre></pre>
</div>
<h4><strong>Server Code (PHP)</strong></h4>
<p>Create <em>postdata.php</em> on your web host:</p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-php" data-lang="PHP"><pre><code class="language-cpp">&lt;?php
if ($_SERVER[&#039;REQUEST_METHOD&#039;] === &#039;POST&#039;) {
    $temp = $_POST[&#039;temp&#039;];
    $hum = $_POST[&#039;hum&#039;];

    $timestamp = date(&#039;Y-m-d H:i:s&#039;);
    $log = &quot;$timestamp, $temp, $hum\n&quot;;
    file_put_contents(&#039;data.csv&#039;, $log, FILE_APPEND);

    echo &quot;OK&quot;;
} else {
    echo &quot;No POST received&quot;;
}
?&gt;</code></pre></pre>
</div>
<p>This writes incoming readings to <em>data.csv</em> on your server.</p>
<h4><strong>Google Apps Script (Alternative Cloud Option)</strong></h4>
<p>If you’d rather log to Google Sheets:</p>
<p>1. Create a new Google Sheet → Extensions → Apps Script.</p>
<p>2. Paste this:</p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-js" data-lang="JavaScript"><pre><code class="language-cpp">function doPost(e){
  var sheet = SpreadsheetApp.getActiveSheet();
  var temp = e.parameter.temp;
  var hum = e.parameter.hum;
  sheet.appendRow([new Date(), temp, hum]);
  return ContentService.createTextOutput(&quot;OK&quot;);
}</code></pre></pre>
</div>
<p>3. Deploy → New Deployment → Web App → “Execute as Me”, “Anyone can access”.</p>
<p>4. Use the generated URL in your Arduino sketch:</p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">sendAT(&quot;AT+HTTPPARA=\&quot;URL\&quot;,\&quot;https://script.google.com/macros/s/XXXXXXXX/exec\&quot;&quot;, &quot;OK&quot;);</code></pre></pre>
</div>
<p><center></center></p>
<h4 style="text-align: left;"><strong>Notes &amp; Tips</strong></h4>
<ul>
<li style="text-align: left;">Replace your.apn.here with your carrier’s APN (e.g., globe.com.ph, smartlte, internet).</li>
<li style="text-align: left;">Keep payload short (&lt; 200 bytes) for reliability.</li>
<li style="text-align: left;">Use delay(2000) between HTTP phases to allow module to process.</li>
<li style="text-align: left;">Use AT+CSQ before posting; ensure RSSI &gt; 10 for stable link.</li>
<li style="text-align: left;">For periodic uploads, wrap the POST block in a loop() timer.</li>
</ul>
<hr />
<h3><strong>Troubleshooting &amp; FAQs</strong></h3>
<p><strong>Q: Why does my SIM800L LED blink then turn off?</strong><br />
A: Your power supply is sagging. Use a 3.7–4.2 V source that can deliver ~2 A bursts and add 100 µF + 1000 µF caps near Vcc.</p>
<p><strong>Q: How do I fix network registration issues (AT+CREG?)</strong><br />
A: Check antenna and coverage, try outdoors, confirm your SIM is active and supports 2G in your region.</p>
<p><strong>Q: Why does the module reset during SMS or HTTP?</strong><br />
A: Power dips during transmission. Use a low-ESR capacitor close to Vcc, thick short wires, and a supply capable of 2 A bursts.</p>
<p><strong>Q: Why do I see garbage on Serial Monitor?</strong><br />
A. Mismatch baud or Serial line noise. Use 9600. Keep UART wires short. On 5 V Arduino, use a level shifter to SIM800L RXD.</p>
<p><strong>Q: What APN should I use for GPRS/HTTP?</strong><br />
A: It depends on your carrier. Set with</p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-bash" data-lang="Bash"><pre><code class="language-cpp">AT+SAPBR=3,1,&quot;APN&quot;,&quot;your.apn&quot;.</code></pre></pre>
</div>
<p>Some carriers require username/password too.</p>
<p><strong>Q: Can I use SIM800L with 3.3 V boards (ESP32)?</strong><br />
A: Yes. Power the module with ~4.0 V and use a hardware UART on ESP32 for reliability. Level shift Arduino TX -&gt; SIM800L RXD if needed</p>
<p><script type="application/ld+json">
{
 "@context": "https://schema.org",
 "@type": "FAQPage",
 "mainEntity": [
  {
   "@type": "Question",
   "name": "Why does my SIM800L LED blink then turn off?",
   "acceptedAnswer": {"@type":"Answer","text":"Your power supply is sagging. Use a 3.7–4.2 V source that can deliver ~2 A bursts and add 100 µF + 1000 µF caps near Vcc."}
  },
  {
   "@type": "Question",
   "name": "How do I fix network registration issues (AT+CREG?)",
   "acceptedAnswer": {"@type":"Answer","text":"Check antenna and coverage, try outdoors, confirm your SIM is active and supports 2G in your region."}
  },
  {
   "@type": "Question",
   "name": "Why does the module reset during SMS or HTTP?",
   "acceptedAnswer": {"@type":"Answer","text":"Power dips during transmission. Use a low-ESR capacitor close to Vcc, thick short wires, and a supply capable of 2 A bursts."}
  },
  {
   "@type": "Question",
   "name": "Why do I see garbage on Serial Monitor?",
   "acceptedAnswer": {"@type":"Answer","text":"Mismatch baud or Serial line noise. Use 9600. Keep UART wires short. On 5 V Arduino, use a level shifter to SIM800L RXD."}
  },
  {
   "@type": "Question",
   "name": "What APN should I use for GPRS/HTTP?",
   "acceptedAnswer": {"@type":"Answer","text":"It depends on your carrier. Set with AT+SAPBR=3,1,\"APN\",\"your.apn\". Some carriers require username/password too."}
  },
  {
   "@type": "Question",
   "name": "Can I use SIM800L with 3.3 V boards (ESP32)?",
   "acceptedAnswer": {"@type":"Answer","text":"Yes. Power the module with ~4.0 V and use a hardware UART on ESP32 for reliability. Level shift Arduino TX -> SIM800L RXD if needed."}
  }
 ]
}
</script></p>
<p><center></center><center></center><center><a href="http://s.click.aliexpress.com/e/BQZbYJ2" target="_parent" rel="noopener noreferrer"><img decoding="async" src="//ae01.alicdn.com/kf/HTB160iUSFXXXXcEaXXXq6xXFXXX5/Free-Shipping-Smallest-font-b-SIM800L-b-font-GPRS-GSM-Module-MicroSIM-Card-Core-BOard-Quad.jpg_220x220.jpg" /><span style="display: block;">Buy Chip SIM800L Modules at AliExpress</span></a></center></p>
<p>The post <a href="https://www.teachmemicro.com/arduino-sim800l-tutorial/">Using SIM800L with Arduino</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.teachmemicro.com/arduino-sim800l-tutorial/feed/</wfw:commentRss>
			<slash:comments>46</slash:comments>
		
		<enclosure url="https://i.imgur.com/e7TVE6y.mp4" length="240081" type="video/mp4" />

			</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Page Caching using Disk: Enhanced 

Served from: www.teachmemicro.com @ 2026-07-28 12:06:31 by W3 Total Cache
-->