Modify Cactus Micro: http://blog.aprbrother.com/p/283 1) convert default serial port to hardware serial (cut/solder) 2) connect Digital pin 5 to ESP8266’s GPIO0 (so arduino sketch at the bottom of this page can pull ESP8266’s GPIO0 to GND - this puts the ESP8266 in program mode to receive firmware update)

Load Arduino programmer sketch - sends computer COM serial straight to ESP8266 hardware serial https://github.com/volca/arduino_esp8266_programmer/blob/master/arduino_esp8266_programmer.ino

Flash firmware. Do NOT use esptool.py. I kept getting this error:

Connecting...
Traceback (most recent call last):
  File "./esptool.py", line 505, in 
    esp.connect()
  File "./esptool.py", line 158, in connect
    raise Exception('Failed to connect')
Exception: Failed to connect

Instead, use the GUI for Node MCU http://randomnerdtutorials.com/flashing-nodemcu-firmware-on-the-esp8266-using-windows/ https://github.com/nodemcu/nodemcu-flasher

Click Config tab Uncheck the internal Node MCU firmware (selected by default) Browse for espduino 0x00000 bin Browse for espduino 0x40000 bin

Enjoy espduino! https://github.com/tuanpmt/espduino

Important: when using the serial passthrough Arduino sketch, don’t change the default baud rate of espduino - I tried to be smart and set it at 9600 – didn’t work.

Below is the “passthrough” sketch I used to stream the firmware from USB through Arduino serial through ESP8266 hardware serial. It’s ugly and there are many other similar sketches, but I’m saving the one I used here, just in case.

/**************************************************
* Simple pass-through serial flash programmer 
* programming the ESP8266 by an Arduino
*
* Any serial data is transfered as-is between the 
* two devices, with one exception:
* Sending data to the Arduino will trigger a reset
* of the ESP8266 into bootloader mode, if it is the 
* first connection attempt since 1 second.
* If no data is send for 1 second, the ESP is reset 
* again into normal mode.
* 
* This resembles the comfortable DTS controlled 
* programming mode one have with an FTDI or similiar
* serial connection cable, where no manual reset of
* the ESP is needed to upload code and run it.
* Unfortunately there is no RTS/DTS control on the
* Arduino Serial library, so we solely rely on timing.
*
* If the esptool does not wait or retry long enough, 
* you have to send some chars to trigger the reset 
* eg. add this to your Makefiles / scripts:
*
* echo 'RESET' >/dev/ttyACM0
* sleep 0.5 
* esptool .....
*
*
* Transmissions from the ESP are passed without any
* modification.
*
* You can not send serial commands (eg. to AT firmware)
* to the ESP with this tool, as it would frequently
* trigger resets into program mode.
*
* TODO: Provide control by magic keywords in the 
* serial data, like 'MAGIC_RESET_TO_BOOTLOADER'. 
* This way we can remove the timeouts and regain 
* interactive bidirectional serial console.
*
* TODO: tighten timings.
*
***************************************************/

/*
* Use an 3.3V Arduino, or TTL level shifter on RX / TX connections!
* The pin 9 / 10 connections are just pulled down, no level shifter is needed here.
* 
* connection table:
* ESP8266  Arduino
* GPIO0    5
* ENABLE   13
* RX       TX
* TX       RX
* GND      GND
* 
* Further connections to GND or VCC are needed depending on the ESP breakout module.
* 
* An LED on Arduino Pin 13 would indicate Program Mode.
*/

int program_pin = 5;
int enable_pin=13;
//int led_pin=13;

void setup()
{
  delay(2000);
  Serial.println("setup ESP8266");
  Serial1.begin(9600);
  Serial.begin(9600);
  pinMode(enable_pin, OUTPUT);
  pinMode(program_pin, OUTPUT);
  digitalWrite(program_pin, LOW);
  Serial.println("enabling ESP8266");
  digitalWrite(enable_pin,HIGH);
  delay(10000);

  Serial.println("ESP8266 programmer ready.");
}

long last_send=0;

// resets the ESP8266 into normal or program / bootloader mode
void reset_target(bool program_mode)
{
    return;
	if(program_mode)
	{
		pinMode(program_pin,OUTPUT);
	}
	else
	{
		pinMode(program_pin,INPUT);
	}
	//digitalWrite(led_pin, program_mode);
	
	delay(100);
	pinMode(enable_pin,INPUT);	
	delay(100);
	pinMode(enable_pin,OUTPUT);
	digitalWrite(enable_pin,HIGH);
	delay(500);
}

bool program_mode=true;
void loop()
{ 
  	while(Serial1.available())
	{
		Serial.write((Serial1.read()));
	}
  
  	// pass data from ESP to host, if any
	while(Serial1.available())
	{
		Serial.write((uint8_t)Serial1.read());
	}

	// pass data from host to ESP, if any
	if(Serial.available())
	{
		// if we are not in program mode, trigger reset to bootloader mode.
		if(!program_mode){
			//reset_target(true);
			program_mode=true;
		}			
		// pass data
		while(Serial.available())
		{
			Serial1.write((uint8_t)Serial.read());
		}
		last_send=millis();
	}

	// if the last transfer is more then one second ago,
	// trigger reset into normal mode.
	//if(last_send>0 && millis()-last_send>1000)
	if(0)
	{
		reset_target(false);
		last_send=0;
		program_mode=false;
	}
}

P.S. You’ll probably want this Arduino library next: ArduinoJSON https://github.com/bblanchon/ArduinoJson/wiki/Using%20the%20library%20with%20Arduino