Hola muy buenas tardes
Mi nombre es Adrian, soy novato con proyectos en ARDUINO, y he estado siguiendo varios post de nickgammon, y foros de discusión en https://forum.arduino.cc, acerca de cómo TRANSFERIR datos entre MASTER y SLAVE usando SPI.
Inicialmente he conectado un ARDUINO NANO como MASTER a un ARDUINO UNO como SLAVE, usando los pines ->
o pin 10 (SS) -> Green
o pin 11 (MOSI) -> Gray
o pin 12 (MISO) -> Orange
o pin 13 (SCK) -> Cyan
o +5v (if required) -> Red
o GND (for signal return) -> Black
También he conectado dos sensores de temperatura 1-DHT11, y 2-DHT11, al Arduino UNO, siendo los cables con señal:
o 1-DHT11 ->Violet ->SGN pin A3
o 2-DHT11 ->Yellow ->SGN pin A2
Les adjunto un esquema de la conexión->
Estos componentes los he conseguido en BANGGOOD:
Geekcreit® UNO R3 ATmega328P Development Board For Arduino No Cable
Digital Temperature Humidity Sensor Module Probe For HVAC Arduino 4pin
Geekcreit® ATmega328P Nano V3 Controller Board Compatible Arduino Improved Version Module
Geekcreit® UNO R3 Improved Version + 2.8TFT LCD Touch Screen + 2.4TFT Touch Screen Display Module Kit For Arduino
Lo que intento conseguir es:
Cuando el MASTER lo solicite (enviando en el primer byte <1> ó <2>), obtener la temperatura registrada por el sensor seleccionado, conectado al SLAVE, transmitir el dato de la temperatura, y ver el resultado en el Monitor Serie asociado al MASTER.
Mi proyecto FINAL será poder visualizar las temperaturas en una pantalla TFT LCD 2.4” conectada al MASTER, dejando de lado la funcionalidad de la SD CARD que tiene el shield mcufriend TFT-LCD 2.4”.
Hasta el momento, los ejemplos dentro de SKETCH encontrados, funcionan para enviar y/o recibir un byte, o una cadena “Hola Mundo\n”, pero cuando intento modificar el código, no he podido hasta el presente obtener un flujo “estable” de datos entre MASTER & SLAVE.
Aunque los datos leídos en los sensores son del tipo float, realizo un “typecast” con int() y transmito SOLO enteros.
Siguiendo con el ejemplo encontrado en el post: Gammon Forum : Electronics : Microprocessors : SPI - Serial Peripheral Interface - for Arduino
Utilizo la estructura ->
// create a structure to store the different data values:
typedef struct tempSTRUCT{
byte ID;
int nroTRANSACTION;
int tempID;
long nroSEQUENTIAL;
};
Para elegir el Sensor DHT11, genero un número aleatorio, y me aseguro de obtener un “byte”
randomT = byte(random(1,3));
// de esta forma obtendré aleatoriamente 1 ó 2
dataSEND.a=randomT;
Finalmente desde el MASTER realizo ->
SPI_writeAnything (dataSEND);
Donde teóricamente debería poder RECIBIR, los datos leídos en el sensor ID DHT11, almacenado en -> dataSEND.a
Bien, en esta parte es donde me pierdo, y NO puedo lograr que las modificaciones realizadas en el SLAVE, se vean reflejadas en el MASTER.
A modo de ejemplo en el código original del sketch realizado por Nick GAMMON, la salida por monitor serie es:
42
32000
101064
42
32000
101065
42
32000
101066
Donde foo.a = 42 y foo.b = 32000 están asignados en el setup() del MASTER.
Y al tener éxito con la instrucción SPI_writeAnything (foo);
En el código del MASTER realizo foo.c++, razón por la cual, en las sucesivas iteraciones se ve el resultado: 101064, 101065, 101066 etc …
Noten que en el código adjunto más abajo del SLAVE, probé realizar lo siguiente:
if ((int)dataSLAVE.a==1){
dataSLAVE.b++;
} else {
dataSLAVE.b--;
}
o su equivalente en el código de Nick foo.b++, ó foo.b- -, que al imprimirse por el monitor serie se ve el cambio MOMENTANEO de la variable <foo.b>
Pero en la siguiente iteración del loop del MASTER, vuelve al valor ORIGINAL que tenía asignado en el setup(), como si no hubiese sido modificado.
18:03:46.116 -> 2
18:03:46.116 -> 12345
18:03:46.116 -> 156
18:03:46.116 -> 100322
18:03:47.094 -> 2
18:03:47.094 -> 12345
18:03:47.094 -> 156
18:03:47.094 -> 100323
18:03:48.117 -> 1
18:03:48.117 -> 12346
18:03:48.117 -> 156
18:03:48.117 -> 100324
18:03:49.092 -> 1
18:03:49.092 -> 12346
18:03:49.092 -> 156
18:03:49.092 -> 100325
Es decir, me falta poder incluir en el código del MASTER ->lo recibido, ACTUALIZARLO en la estructura definida.
¿Podría alguien ayuudarme a corregir este concepto al cual NO le puedo encontrar solución?
¿Es que necesito realizar transferencias INDIVIDUALES por cada variable de la estructura generada?
Desde ya agradezco su gentil colaboración,
Adrian RUFFATO
MASTER CODE
#include <SPI.h>
#include "SPIanything.h"
// create a structure to store the different data values:
typedef struct myStruct{
byte a; // byte with ID
int b; // int N° transaction
int c; // int temp * 10 -> float(temp/10.0)
long d; // long, increment to view data TRANSFER
//char e;
};
volatile myStruct dataSEND;
volatile myStruct dataRECEIVED;
void setup (){
SPI.begin ();
Serial.begin(115200);
// Slow down the master a bit
SPI.setClockDivider(SPI_CLOCK_DIV128);
dataSEND.a = 2; // byte with ID
dataSEND.b = 12345; // int N° transaction
dataSEND.c = 156; // int temp * 10 -> float(temp/10.0)
dataSEND.d = 100000; // long, increment to view data TRANSFER
// dataSEND.str = "M"; // not available, for future uses
} // end of setup
byte randomT; // ID of the DHT's random access
void loop (){
digitalWrite(SS, LOW); // SS is pin 10
randomT = byte(random(1,3));
dataSEND.a=randomT;
SPI_writeAnything (dataSEND);
// *************************************************
// I make a probe with the next sentences, but I only receive (0)
//
//SPI_readAnything (dataRECEIVED);
// *************************************************
digitalWrite(SS, HIGH);
delay (100); // for testing
// *******************************************************
// Something like this, is what I think I need to RECEIVED from SLAVE
// dataSEND.b=dataRECEIVED.b;
// *******************************************************
dataSEND.d++; // <- this work OK
} // end of loop
SLAVE CODE
#include <SPI.h>
#include "SPIanything.h"
// create a structure to store the different data values:
typedef struct myStruct{
byte a; // byte with ID
int b; // int N° transaction, no matter if increment, or decrement
int c; // int temp * 10 -> float(temp/10.0)
long d; // long, increment to view data TRANSFER loop
//char e;
};
volatile myStruct dataSLAVE;
volatile bool haveData = false;
void setup (){
Serial.begin (115200);
// have to send on master in, *slave out*
// ***************************************
// * Forma de preparar el SLAVE
// ***************************************
pinMode(MISO, OUTPUT);
// pinMode(MOSI, INPUT);
// pinMode(SCK, INPUT);
// Ver el gráfico en blog de gammon.com.au
// _______________________________________
// turn on SPI in slave mode
SPCR |= _BV(SPE);
// now turn on interrupts
SPI.attachInterrupt();
} // end of setup
void loop (){
if (haveData){
if ((int)dataSLAVE.a==1){
dataSLAVE.b++;
// ************************************
// * To obtain temperature from 1-DHT11
// ************************************
//float tA = dhtA.readTemperature();
//dataSLAVE.b = int(tA*10);
} else {
//dataSLAVE.b--;
// ************************************
// * To obtain temperature from 2-DHT11
// ************************************
//float tB = dhtB.readTemperature();
//dataSLAVE.b = int(tB*10);
}
Serial.println ((int) dataSLAVE.a);
Serial.println (dataSLAVE.b);
Serial.println (dataSLAVE.c);
Serial.println (dataSLAVE.d);
//Serial.println (dataSLAVE.str);
haveData = false;
// **********************************
// * This do not work ->
// digitalWrite(SS, LOW); // SS is pin 10
// SPI_writeAnything (dataSLAVE);
// digitalWrite(SS, HIGH);
// **********************************
delay (20); // for testing
}
} // end of loop
// SPI interrupt routine
ISR (SPI_STC_vect){
SPI_readAnything_ISR (dataSLAVE);
haveData = true;
} // end of interrupt routine SPI_STC_vect
MasterSlave.pdf (795 KB)