Interrupts with the TRINKET analog comparator

July 12, 2015 Leave a comment

Here I’m sharing a working example using the analog comparator of the Adafruit’s  TRINKET (ATtiny85).

Trinket_ISR

 

/*Trinket_comp_ISR.ino  Arduining.com 12 JUL 2015
  Sketch to test interrupts fron the analog comparator.
  2.5 Volt in ANI0 (voltage divider).
  Potentiometer input in ANI1  An interrupt is generated in every change of the comparator output (toggle).
  The interrupt set the flag  "triggered".
  The main loop program checks for the flag, if the flag is set, test the output value  of the comparator
  and modify the state of the LED according.*/

#define LED 4 

volatile boolean triggered=false;

//------------ Analog Comparator Interrupt Routine ----------------------------
ISR(ANA_COMP_vect){  
  triggered = true;
}
  
//-----------------------------------------------------------------------------
void setup(){
 pinMode(LED,OUTPUT);
  ADCSRB &= ~(1<<ACME);             //Set AIN1 as the negative input (Potentiometer).
  DIDR0 |= (1<<AIN1D)|(1<<AIN0D);   // disable digital inputs.
  
//ACSR – Analog Comparator Control and Status Register   
  ACSR = B00001000; // comparator interrupt enabled and tripped on toggle. (compare with AN1)
      //  ||||||||_ ACIS0 ACIS1, ACIS0: Analog Comparator Interrupt Mode Select
      //  |||||||__ ACIS1 10= falling edge; 11= raising edge; 00= toggle.
      //  ||||||___ ACIC  Reserved Bit
      //  |||||____ ACIE  Interrupt Enable
      //  ||||_____ ACI   Analog Comparator Interrupt Flag (R/W), write 1 to clear it.
      //  |||______ ACO   Analog Comparator Output (read only)
      //  ||_______ ACBG  1= Bandgap Select (1.1V); 0= compare with AIN0 (pin 6)
      //  |________ ACD   Analog Comparator Disable


  digitalWrite(LED, HIGH);//LED on for 100 milliseconds.
  delay(100);
  //Put the LED status as the analog comparator output (inverted)
  if(ACSR & (1<<ACO))digitalWrite(LED, LOW);
  else digitalWrite(LED, HIGH);
}

//-----------------------------------------------------------------------------
void loop(){
  if(triggered){
    if(ACSR & (1<<ACO))digitalWrite(LED, LOW);
    else digitalWrite(LED, HIGH);
    triggered= false;
    //while(1){}
  }
}


Arduino and Two Stepper Motors

May 30, 2015 4 comments

 

Two_Steppers

This project consist in moving two stepper motors “simultaneously”.
Really there is a loop where both motors are moved “one step at a time” to reach their final position.
5 Volts steppers with external power source are used.

 

Here is the video in YouTube:

Here is the Sketch:

—————-

/*------------------------------------------------------
Two_Steppers.ino     Arduining.com  30 MAY 2015

Driving two steppers concurrently with the Arduino Nano.
stepperX follows potentiometer on analog input 0.
stepperY follows potentiometer on analog input 1.
A timeout is used to turn off coils and save energy in battery
operated applications.

Hardware:
Arduino NANO.
Drivers: ULN2003A
Stepper Motors: 28BYJ48, 5VDC, step angle 5.625 °
                Gear reduction 64:1
                No-load starting frequency:> = 500PPS (4 rpm)
                Coil resistance 60 Ohms.               
 -----------------------------------------------------*/

#include <Stepper.h>

#define  STEPSREV    4096    // 64(fullsteps) * 64 (reduction ratio)
#define  SPEED       4       // motor speed (RPM)

#define  COIL_1X     11
#define  COIL_2X     9
#define  COIL_3X     10
#define  COIL_4X     8

#define  COIL_1Y     7
#define  COIL_2Y     5
#define  COIL_3Y     6
#define  COIL_4Y     4

#define  POT_X       0
#define  POT_Y       1                
#define  TIMEOUT     1000    //Turns off after 1 sec of inactivity.
#define  NOISE       8       //inmunity in steps because analog noisy readings.

// create the instances of the stepper class.
Stepper stepperX(STEPSREV, COIL_1X, COIL_2X, COIL_3X, COIL_4X);
Stepper stepperY(STEPSREV, COIL_1Y, COIL_2Y, COIL_3Y, COIL_4Y);

int potValX,potValY;           // potentiometers analog readings
int Xpos,Ypos;                 // Actual steppers positions(0-4096)->(0-360°)
int newXpos, newYpos;          // New steppers positions
unsigned long stampX, stampY;  // last move time stamped.

//============== functions ====================================================

//Read the potentiometers and map the reading to mach 360 degrees.
void readPots(){
  potValX = analogRead(POT_X);          // read POT_X value (0-1023).
  potValY = analogRead(POT_Y);          // read POT_Y value (0-1023).
  newXpos= map(potValX,0,1023,0,2047);  // Map pot X range to one stepper turn.
  newYpos= map(potValY,0,1023,0,2047);  // Map pot Y range to the stepper turn.
}
 
//-----------------------------------------------------------------------------
// Aproach stepperX to the newX position.
void aproachX(int newX){
  int Xdir = Xpos<newX ? 1 : -1;
  stepperX.step(Xdir);        // move one step in the Xdir direction.
  Xpos += Xdir;               // update Xpos.
  stampX = millis();          // stamp actual time.
  }

//-----------------------------------------------------------------------------
// Aproach stepperY to the newY position.
void aproachY(int newY){
  int Ydir = Ypos<newY ? 1 : -1;
  stepperY.step(Ydir);        // move one step in the Ydir direction.
  Ypos += Ydir;               // update Ypos.
  stampY = millis();          // stamp actual time.
  }

//-----------------------------------------------------------------------------
//Check for inactivity and turn off the steppers coils to save battery.
void CheckTimeout(){
  if((millis() - stampX) > TIMEOUT){   //Turn Off StepperX coils.
    digitalWrite(COIL_1X, LOW);
    digitalWrite(COIL_2X, LOW);
    digitalWrite(COIL_3X, LOW);
    digitalWrite(COIL_4X, LOW);
  }
  if((millis() - stampY) > TIMEOUT){   //Turn Off StepperY coils.
    digitalWrite(COIL_1Y, LOW);
    digitalWrite(COIL_2Y, LOW);
    digitalWrite(COIL_3Y, LOW);
    digitalWrite(COIL_4Y, LOW);
  }    
}


//=================== setup ===================================================
void setup(){
  stepperX.setSpeed(SPEED);  // set the X motor speed.
  stepperY.setSpeed(SPEED);  // set the Y motor speed.
  readPots();
  Xpos = newXpos;
  Ypos = newYpos;
}

//================= main loop =================================================
void loop(){
  readPots();
//if diference is greater than NOISE move steppers.
  if(abs(newXpos - Xpos)> NOISE) aproachX(newXpos);
  if(abs(newYpos - Ypos)> NOISE) aproachY(newYpos);

  CheckTimeout();   //check for inactivity.

}

 

—————-

 

 

 

 

 

Serial Commands to Arduino ( LED control )

May 4, 2015 2 comments

Serial_LED_control A small sketch to show how to implement a command menu using the Serial Monitor of the Arduino IDE. In this example the switch statement is used to identify the received command and execute the corresponding action.

— Command list: —

? -> Print this HELP

a -> LED On  “activate”

d -> LED Off “deactivate”

s -> LED     “status”


The SKETCH:

/*Serial_LED_02.ino  Arduining 4 May 2015
Controlling the LED in pin 13 with the Serial Monitor.
--- Command list: ---
? -> Print this HELP 
a -> LED On  "activate"
d -> LED Off "deactivate"
s -> LED     "status" 

Example using the switch statement.
*/
 
#define LED 13          // Pin 13 is connected to the LED
char rxChar= 0;         // RXcHAR holds the received command.

//=== function to print the command list:  ===========================
void printHelp(void){
  Serial.println("--- Command list: ---");
  Serial.println("? -> Print this HELP");  
  Serial.println("a -> LED On  \"activate\"");
  Serial.println("d -> LED Off \"deactivate\"");
  Serial.println("s -> LED     \"status\"");  
  }
  
//---------------- setup ---------------------------------------------
void setup(){
  Serial.begin(9600);   // Open serial port (9600 bauds).
  pinMode(LED, OUTPUT); // Sets pin 13 as OUTPUT.
  Serial.flush();       // Clear receive buffer.
  printHelp();          // Print the command list.
}

//--------------- loop ----------------------------------------------- 
void loop(){
  if (Serial.available() >0){          // Check receive buffer.
    rxChar = Serial.read();            // Save character received. 
    Serial.flush();                    // Clear receive buffer.
  
  switch (rxChar) {
    
    case 'a':
    case 'A':                          // If received 'a' or 'A':
	if (digitalRead(LED) == LOW){        // If LED is Off:
          digitalWrite(LED,HIGH);      // Turn On the LED.
          Serial.println("LED turned On");
	}
        else Serial.println("LED already On!");
        break;

    case 'd':
    case 'D':                          // If received 'd' or 'D':
	if (digitalRead(LED) == HIGH){       // If LED is On:
          digitalWrite(LED,LOW);       // Turn Off the LED.
          Serial.println("LED turned Off");
	}
        else Serial.println("LED already Off!");
        break;
        
    case 's':
    case 'S':                          // If received  's' or 'S':
	if (digitalRead(LED) == HIGH)        // Read LED status.
          Serial.println("LED status: On");
        else Serial.println("LED status: Off");
        break;
        
    case '?':                          // If received a ?:
        printHelp();                   // print the command list.
        break;
        
    default:                           
      Serial.print("'");
      Serial.print((char)rxChar);
      Serial.println("' is not a command!");
    }
  }
}
// End of the Sketch.

Digital To Analog with Tiva C Launchpad and Energía

April 17, 2015 Leave a comment

TIVA_C_and_energia2



There are nice Energía diagrams for this LaunchPad in the Web.

Nevertheless, to become familiar with the board functionality and pin layout (and because enjoy drawing) decided to make a diagram. Tiva C Launchpad Pinout Diagram :

Tiva_C_Launchpad_Pinout_001b

Since my first contact with Arduino always wanted to generate waveforms and see them in an oscilloscope. Almost three years ago made some projects with the MSP430 LaunchPad, can be seen at the SeuPay’s YouTube channel. Then also did some test with the Stellaris LaunchPad.

After more than a year with a couple of unboxed Tiva C LaunchPads, decided to try some waveforms generation with the inexpensive 32 bit, 80 MHz ARM platform. Using Energía, began some experiments with the Tiva C :

-Generating waves with the MCP4725, I2C 12-Bits DAC .

-Generating waves with the AD7801 Parallel 8-Bit DAC.

Direct Port Manipulation was used to reach higher data updates (samples/second).



 

Tiva C Launchpad and MCP4725

The first experiment generates wave shapes using an external DAC (Digital-To-Analog Converter).

The first choice was to use the MCP4725 from Adafruit’s (SparkFun also has a version with different address).

TIVA_C_MCP4725_wiring

The following sketch fills an array with the values of a sine wave and feeds the  DAC continuously with those values.

The “Fast Mode Write Command” of the MCP4725 is used.


/*MCP4725_Sin_01.ino   Arduining 17 APR 2015

-Energia Sketch to be used with Tiva C Launchpad and the Adafruit's MCP4725.
-I2C Fast Mode Write Command is used.
-120 samples are producing a 3.62Hz sine wave  => 434 samples/second.

Based in the code at:
http://electronics.stackexchange.com/questions/29457/how-to-make-arduino-do-high-speed-i2c
 
*/

#include 
#include 

//The MCP4725 from Adafruit:
//  I2C address is 0x62 ( by default A0 has a 10k pull-down resistor ).
//  I2C address is 0x63 if A0 is connected to VCC. 
#define MCP4725_ADDR 0x62           //I2c address..

int ch[ 360 ] , cl[ 360 ];          //Arrays to load the sine wave.

//------------------------------------------------------------------------
void setup() {

  Wire.begin();           // SCL(3) and SDA(3) by default in Tiva C.
  Wire.setModule(0);      // Changing to SCL(0)and SDA(0),(PB_2 and PB_3). 

  analogWrite(GREEN_LED,25);        //led 10% on.
  
// Create a sine table of 360 points:
  for ( int i = 0; i <= 360; i++ ) {
    int c = sin( i * 3.141592 / 180 ) * 2047 + 2048;
    ch[ i ] = int( c / 256 );      // the 4 most significant bits.
    cl[ i ] = c - ch[ i ] * 256;   // the 8 least significant bits.
  }
}

//------------------------------------------------------------------------
void loop() {
  for ( int i = 0; i < 360; i=i+3 ) {     //Only 120 points are used.
    Wire.beginTransmission(MCP4725_ADDR);
    //Fast Mode Write Command.
    Wire.write( ch[ i ] );        // the 4 most significant bits.
    Wire.write( cl[ i ] );        // the 8 least significant bits.
    Wire.endTransmission();
  }
}

This is the final result.

TivaC_MCP4725_01

The DSO Nano is very handy because fits anywhere close to my desktop computer and

has become an excellent and inexpensive monitor for debugging.

DSO Nano screen capture of a  simulated ECG wave (using the same hardware):

AD7801_ECGsmall_2


 

Working with C and Direct Registers (and Ports) Manipulation

Thanks to the page: http://users.ece.utexas.edu/~valvano/Volume1/E-Book/

Where the professor Valvano, from University of Texas at Austin, teach how to Develop Embedded Systems with the ARM M 4 Processor (Tiva C LaunchPad).

The chapters are mainly designed to work in C but, with some adjusts, the Energía environment does pretty good.

To enable Direct Register Manipulation we need to include in Energía the hardware register definitions.

Just write at the beginning of your code:

#include

This file is located in: C:\energia-0101E0015\hardware\lm4f\cores\lm4f\inc

I just made a copy and put it in: C:\energia-0101E0015\hardware\lm4f\libraries\tm4c123gh6pm

Notice that the file was copied inside a folder created with the same name.

(Surely there is a path to be included in Enegía to do this in a more elegant way).

Now you can use the Valvano’s examples in the Energía IDE, just remember to split the code appearing inside the main() function in two parts:

  – The configuration code goes inside the setup() function of Energía.

  – And the code running continuously is located inside the loop() function of Energía.

Is also possible to include Assembly code in Energía, but it needs another post.


 

Wiring the AD7801 8-Bits Parallel Digital to Analog Converter

A parallel DAC with 8 Bits is chosen to make the data transfer very fast.

Found the AD7801  at Mouser, the problem: (No DIP Package).

OK, let’s do some SMT work. With the DAC ordered and a  20 contact SOIC-to-DIP adapter.

…some SMT manual soldering…Breadboard-adapter-AD7801_02

A wiring diagram to connect the AD7801 to the Tiva C LaunchPad:

Tiva_C_AD7801_wiring

The AD7801, once soldered and wired, is very easy to operate. Simply put a new data in the PORTB and toggle PORTA bit 2 to produce a low pulse in the WR signal.

Did a A Quick-Ref of the chip:

QuickRef-AD7801

Then I had to study  Valvano’s code to understand how to deal with the Direct Register (and Ports) Manipulation.

First began to do the I/O Ports setup using the Direct Register manipulation, this part is not necessary, you can use Arduino code in Energía to do it. But was a good opportunity to learn  some details of the the ARM  Cortex M 4.

Finally, the code used to generate the fast data transfer between Tiva C launchpad and the AD7801:


/*AD7801_FastDAC.ino  Arduining.com 18 APR 2015

Testing the Tiva C LaunchPad and the AD7801 (Parallel Input 8-Bit DAC).
Using the PORTB to write the 8-Bit data.
Using PORTA bit 2 for the write signal (WR).

Results:
6 kHz    POINTS=256   ==>  1,536 Mega-samples/sec.
96 kHz   POINTS=16    ==>  1,536 Mega-samples/sec.
Note: faster if offset is a char.( 1,9 Mega-samples/sec.)
-----------------------------------------------------------------------------*/

#include     // TM4C123GE6PM Register Definitions.
#include             // To calculate the sine table.

// bits 7-0 of port B address (Data).
#define ldata     (*((volatile unsigned long *)0x400053FC))
// bit 2 of port A address (WR signal).
#define wrsignal  (*((volatile unsigned long *)0x40004010))

#define POINTS    256    // Wave points.(256 max. to keep offset as char type)
#define PEAKVAL   128    // Wave Amplitud (128 max, inside 8-Bits range)
#define OFFSET    128    // Center of the wave (128 for full 8-Bits span).

int sintable[POINTS];    // Array to load the sin table data.
int offset=0;           // index to point the data inside sintable[].

//------------------------------------------------------------------------------
void setup(){

  PortB_Init();
  PortA_Init();

  // Fill the sin table with POINTS samples:
  for ( int i = 0; i <= POINTS; i++ ) {
    sintable[i] = sin( i * 3.141592 * 2 / POINTS ) * (PEAKVAL-1) + OFFSET ;
  }

}

void loop(){
    //Write data to the AD7801

    ldata= sintable[offset];        // Load value in the port B.
    wrsignal= 0;                    // WR signal to low.
    wrsignal= 4;                    // WR signal to high
    offset++;
    if((POINTS-offset)<=0)offset=0; // Keep offset in range.

  //  delayMicroseconds(2);           // To experiment different frequencies.
}

/*------------------------------------------------------------------------------
Subroutine to initialize port B all pins output.
Port B is used to output the data.
------------------------------------------------------------------------------*/
void PortB_Init(void){
  volatile unsigned long delay;
  SYSCTL_RCGC2_R |= 0x02;          // 1) activate Port B clock
  delay = SYSCTL_RCGC2_R;          // allow time for clock to stabilize
                                   // 2) no need to unlock PB7-0
  GPIO_PORTB_AMSEL_R &= ~0xFF;     // 3) disable analog functionality on PB7-0
  GPIO_PORTB_PCTL_R = 0x00000000;  // 4) configure PB7-0 as GPIO
  GPIO_PORTB_DIR_R |= 0xFF;        // 5) set PB7-0 as outputs
  GPIO_PORTB_AFSEL_R &= ~0xFF;     // 6) disable alt funct on PB7-0
  GPIO_PORTB_DR8R_R |= 0xFF;       // enable 8 mA drive on PB7-0
  GPIO_PORTB_DEN_R |= 0xFF;        // 7) enable digital I/O on PB7-0
}  

/*------------------------------------------------------------------------------
Subroutine to initialize port A pin 2 as output.
PA2 is used to drive the WR signal of the DAC.
------------------------------------------------------------------------------*/
void PortA_Init(void){
  volatile unsigned long delay;
  SYSCTL_RCGC2_R |= 0x01;           // 1) activate clock for Port A
  delay = SYSCTL_RCGC2_R;           // allow time for clock to start
                                    // 2) no need to unlock PA2 
  GPIO_PORTA_PCTL_R &= ~0x00000F00; // 3) regular GPIO 
  GPIO_PORTA_AMSEL_R &= ~0x04;      // 4) disable analog function on PA2 
  GPIO_PORTA_DIR_R |= 0x04;         // 5) set direction to output 
  GPIO_PORTA_AFSEL_R &= ~0x04;      // 6) regular port function 
  GPIO_PORTA_DEN_R |= 0x04;         // 7) enable digital port PA2
}
//End of code.


The complete assembly:

AD7801_FastSin_r

Two screenshots, thanks to the DSO Nano’s image capture function:

 A 6  kHz sine wave using POINTS= 256

and  a 95 kHz sine wave with POINTS= 16 .

The transfer speed is 1.536.000 samples/second.

AD8701_Speed_Test_2


 

Next steps:

Now we have a Sine Wave Generator, but the microcontroller is busy with this simple task.

If we need to do additional tasks like:

  • Change the frequency and (or) the amplitude on the fly.
  • Show  those values in a display.
  • Receive commands or transmit parameters serially.

 We need to use interruptions…

Thanks for reading Arduining blog.


Arduino Pro Trinket Pinout Diagram

April 2, 2015 Leave a comment

Here is my quick reference to wire the Adafruit’s Pro Trinket.

Following the color sheme of the previous published Trinket pinout diagram.

http://arduining.com/2014/01/30/arduino-trinket-pin-diagram/

Pro_Trinket_pins_01

Pins A0-A5 can also be named as 14-19 for digital I/O ( digitalRead() and digitalWrite() ).


Very handy arduinos…

Four_Pro_trinkets

I’ll be posting some project with them…

My first approach was making a Christmas tree star, using Neopixels, last December…

B50LQdFIUAApVGn

Mini Client with the Arduino TRINKET and the ESP8266

January 19, 2015 13 comments

ending the temperature to a ThingSpeak channel using the TMP35 sensor.

This is a small and low cost implementation of IoT (Internet of Things, possibly one of the next technological revolutions). Mini-Client-Trinket-ThingSpeak The ESP8266 can be used alone thanks to the apparition of several environments like LUA, C, Micro Python etc.. In this case I wanted to keep the solution in the Arduino environment to take advantage of many ready-to-use libraries and examples. Then I realized, due the reduced space in the Trinket (5.310Kb for code), the usability of such libraries it’s not so simple. Programming the ATtiny85 with an ISP programmer will permit the use of the full 8K programming memory. Anyway was a fun project, is great to see the small ATtiny85 acting as a Web Client. Let’s make the Trinket do the job using just the Arduino IDE.


Power considerations: The ESP8266 is power hungry when is communicating with a Wi-Fi spot. It can reach 215mA in Transmit Mode. The 3.3Vregulator in the Trinket only supply 150mA max. Then we need to use another 3.3V power source. The L4931 (250 mA) is working at first. A 470 uF capacitors is needed at the output.


Wiring diagram: (….. on the works)


Making the ESP8266 breadboard friendly:  To modify the ESP8266 we need a 0.1″ 4-pin right-angle male header. The procedure is very simple:ESP8266-breadboard-09 First cut (remove) the row of pines closer to the board border. Then, using a breadboard as guide and support, sold the right-angle header. Use enough solder to obtain a good mechanical resistance.     More images in this post: http://arduining.com/2015/01/02/making-esp8266-breadboard-frienly/


Mini breadboard wiring:

MiniClient_wiring

Wire color identification:

Black: ground.

Red: +5V.

Orange: 3.3V from the L4931 regulator.

Yellow: Trinket RX data (ESP8266 TX).

Purple: Trinket TX data (ESP8266 RX).

Blue: ESP8266 reset.

Green: Trinket analog input (TMP36 Vout).


Final assembly:

MiniClient_assembled

Everything in it’s place… let’s coding…


Temperature Sensor TMP35: TMP35_chart


The Trinket Sketch: At first, just ported the code from a working example made with the Meduino NANO and the DHT22 temperature sensor, finding out that the code size will be a problem. open-style-packaging-2


Several changes were implemented to reduce the code size: Changing to the TMP35 temperature sensor because is easier to read (don’t need a library ). Avoiding the use of string manipulation functions. Avoiding the use of floating math operations. (Only integer math was used). Integrating CR and LF at the end of the strings and using print() function instead of println(). Many other changes until the compiler of the Arduino IDE announced:

Binary sketch size: 4,748 bytes (of a 5,310 byte maximum)


The Sketch:

/*ESP8266_Trinket_01.ino Arduining.com (29 APR 2015)
Sending temperature data to ThingSpeak.
Hardware:
 -Adafruit's Arduino Trinket (3.3V)
 -ESP8266(ESP-01)
 -Temperature sensor TMP35

Data update rate set by the SPERIOD value.
Using SoftwareSerial at 9600 bauds.
String and math functions avoided.
The temperature is not calibrated.
  -ATtiny85 internal reference differs a little from 1.1V
  -The TMP35 is affected by radio frequencies.

Sketch uses 4,748 bytes (89%) of program storage space. Maximum is 5,310 bytes.
-----------------------------------------------------------------------------*/

#include <SoftwareSerial.h> 

//Network parameters and server IP address:
#define mySSID    "XXXXXXXXX"           //WiFi network ID.
#define myPASS    "XXXXXXXXX"           //Password.
#define serverIP  "184.106.153.149"     //IP of ThingSpeak.com
#define ChannKEY  "XXXXXXXXXXXXXXXX"    //ThingSpeak channel key.

#define updField  "1"                   //Updating Field( 1,2,3,4,5...)
#define SPERIOD   30000                 //Sampling period (milliseconds).
#define MAXFAILS  10                    //Number of fails to RESET the ESP8266.

//Concatenating the string messages:
#define mode_MSG  "AT+CWMODE=3\r\n"       //Dual mode (Station and Access Point).
#define join_MSG  "AT+CWJAP=\"" mySSID "\",\"" myPASS "\"\r\n"      //set data to join the AP.
#define conn_MSG  "AT+CIPSTART=\"TCP\",\"" serverIP "\",80\r\n"     //TCP, ThingSpeak, port 80.
#define send_MSG  "AT+CIPSEND=46\r\n"     //Send data, size=46 (4 bytes for the value)
#define upda_MSG  "GET /update?key=" ChannKEY "&field" updField "=" //Updating Field data.
#define clos_MSG  "AT+CIPCLOSE\r\n"       //Close TCP connection.


//Trinket pins assignament:
#define RXDATA    1      // SoftwareSerial receive pin (RED LED connected).
#define TXDATA    0      // SoftwareSerial transmit pin.
#define HRESET    3      // Pin to hardware Reset the ESP8266
#define ANATEMP   1      // Analog channel 1 for temperature measurement.

int i,j;
int fails=100;           // set failures>MAXFAILS to generate initial RESET.
unsigned int temp;       // Use positive range values (0-32768)
String tempVal="00.0";   // Four characters (fixed format number).

SoftwareSerial ESPSerial(RXDATA, TXDATA);   // Creates SoftwareSerial channel.

//====================== Setup ================================================
void setup(){
  
  analogReference(INTERNAL);        //Use the 1.1V internal reference.
  pinMode(HRESET,OUTPUT);           //hardware reset for the ESP8266.
  ESPSerial.begin(9600);
  initESP();                        // ESP8266 init.

}   //END of setup.

//====================== loop =================================================
void loop(){

  while((millis() % SPERIOD)>10){};   //Wait for the next multiple of SPERIOD.

  while(ESPSerial.read()!= -1){};     //Wait until no serial data available.

//------------- Here is the temperature reading for the TMP35 ------------------
/*-------------------------------------------------------------------
    For compactness of the code, integer math is used:
    TheTMP35 has 10 mV/°C scale factor:Temp in °C = (Vout in mV)/10 
    With Vref=1.1V the range is: 0°C to +60°C, (0.1 degree resolution)
    AnalogRead value (559) => 60 degree.
    32768/1024= 32 (maximum multiplier to keep the integer positive).
    Multiplier and divider factors are: 29/27= 1.0740 close to 1100/1024.
 --------------------------------------------------------------------*/
  temp= (analogRead(ANATEMP)* 29)/27;  //value in millivolts (1.1V internal ref.)

//------ formating the integer temp to a 4 character string ---------  
  tempVal[0]= '0'+(temp/100);
  tempVal[1]= '0'+(temp%100/10);
//  tempVal[2]= '.';   //decimal point already there.
  tempVal[3]= '0'+(temp%10);

  updateValue();
  if (fails > MAXFAILS) initESP();   //Reset and init ESP8266 after some fails.

}   // END of loop.

/*-----------------------------------------------------------------------------
Function updateValue() 
-----------------------------------------------------------------------------*/
void updateValue(){
  ESPSerial.print(conn_MSG);        //Open TCP connection with ThingSpeak.
  if(waitChar('K',10000)){          //Wait for 'K' of "OK".
    delay(250);                     //Delay to receive the message "Linked"
    ESPSerial.print(send_MSG);      //Send message AT+CIPSEND= and size.
    if(waitChar('>',10000)){        //Wait for '>'.
      ESPSerial.print(upda_MSG);    //Update Field value.
//      tempVal= "13.4";
      ESPSerial.print(tempVal);
//      ESPSerial.print("20.7");    // test value
      ESPSerial.print("\r\n");      //to replace println (less code).
      fails=0;                      // clear failure counter.
      return;                       // Unlink automatically....
    }
  }
  fails++;
  ESPSerial.print(clos_MSG);       //Close the TCP connection with ThingSpeak.  
}

/*-----------------------------------------------------------------------------
Function waitChar() 
-----------------------------------------------------------------------------*/
bool waitChar(char Wchar, int duration){
  for(i=duration;i>0;i--){
    delay(1);
    if(ESPSerial.read()== Wchar)return true;
  }
  return false;
}

/*-----------------------------------------------------------------------------
Function initESP() 
-----------------------------------------------------------------------------*/
void initESP(){
  while(1){
    if (fails > MAXFAILS){           //------Hardware reset for ESP8266.
      digitalWrite(HRESET,LOW);
      delay(100);
      digitalWrite(HRESET,HIGH);
      delay(5000);
      fails=0;
    }

    ESPSerial.print("AT\r\n");       //"\r\n" to replace println  (less code)
    delay(1000);
    if(waitChar('K',1000)){          //Wait for 'K' of "OK".
      ESPSerial.print(mode_MSG);     //Set Station mode.
      delay(250); 
      ESPSerial.print(join_MSG);     //Set name and password of the AP.
      if(waitChar('K',10000))return; //Wait for 'K' of "OK" to exit setup
    }
    fails++;
  }

}


Mini Client part list :

Adafruit-Part-List

Pictures from the Adafruit Industries web page.

1.- USB cable – A/MiniB. (1)
2.- Hook-up Wire 22AWG Solid Core (assorted colors) .(1)
3.- Tiny breadboard 170 contacts. (1)
4.- Adafruit’s Trinket – Mini Microcontroller – 3.3V Logic. (1)
5.- 3.3V 250mA Linear Voltage Regulator – L4931-3.3 TO-92. (1)
6.- 10uF 25V Electrolytic Capacitor. (1)
7.- 470uF 25V Electrolytic Capacitor. (1)
8.-TMP35 – Analog Temperature sensor. (1)
9.- ESP8266 WiFi Module. (1)

NOTE: A 0.1″ 4-pin right-angle male header is recommended to adapt the ESP8266 to the breadboard.


This Post Is Under Construction…

28 APR 2015 : New wiring,  Sketch posted.

… More info when requested and (or) available.

Thanks for reading.


Making ESP8266 breadboard friendly

January 2, 2015 5 comments

Just receive some samples of the ESP-01 board. My first thought was how to use it with a breadboard?.

Doing some Web research found several custom adapters and DIY ideas.

After some brainstorming and a couple of coffees find out a simple procedure to have the ESP8266 nicely plugged in my breadboard.

The solution implies to cut four pins and solder a four pin 0.1 right-angle male header.

IMG_20141231_181709

The adhesive silicone dot helps to plug the module leveled.

 


 

 

The following images explain  themselves:

ESP8266-breadboard-friendly

IMG_20141231_181832

 


 

Ready for IoT fun projects…

ESP8266-Meduino-NANO


 

Sending random values of temperature and humidity to ThingSpeak:

ESP8266-Meduino-Thingspeak



 

Follow

Get every new post delivered to your Inbox.

Join 33 other followers