Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

do TVOut block or interfere with SPI communication? #144

Open
orangefabri opened this issue Dec 23, 2022 · 2 comments
Open

do TVOut block or interfere with SPI communication? #144

orangefabri opened this issue Dec 23, 2022 · 2 comments

Comments

@orangefabri
Copy link

orangefabri commented Dec 23, 2022

Hello.

I have two arduino nano.

one is master, and one is slave.

master sends 2 int16_t variables and 1 double variable.

slave receives it successfully unless there are TVOut code.

if I add TVOut, the result data corrupted.
(expected result : 1111,2222,3333.3, actual result : -18703, -0.00 like this)

is TVOut interfering the data?

Master Code :

void Video(int16_t torque_value, int16_t hook_value, double gyro_value)
{
  int8_t SPI_Buffer[50];
  static int spi_index_test = 0;
  static int spi_index = 0;
  
  SPI_Buffer[0] = *(int8_t *)(&gyro_value); 
  SPI_Buffer[1] = *((int8_t *)(&gyro_value)+1);
  SPI_Buffer[2] = *((int8_t *)(&gyro_value)+2);
  SPI_Buffer[3] = *((int8_t *)(&gyro_value)+3);
  SPI_Buffer[4] = *(int8_t *)(&hook_value);
  SPI_Buffer[5] = *((int8_t *)(&hook_value)+1);
  SPI_Buffer[6] = *(int8_t *)(&torque_value);
  SPI_Buffer[7] = *((int8_t *)(&torque_value)+1);

  
  if(!digitalRead(VIDEO_INT));
  {
    SPI.beginTransaction(setting_video); 
    #ifdef SS_VIDEO_D4
    PORTD &= ~B00010000; //PORTD : 0~7
    #endif
    
    spi_index_test = SPI.transfer(SPI_Buffer[spi_index]);
    if(spi_index_test >= 0)
    {
      spi_index = spi_index_test;
    }

    PORTD |= B00010000; //PORTD : 0~7
    SPI.endTransaction();
  }
}

Slave code :

#include <SPI.h>
#include <TVout.h>
#include <fontALL.h>

TVout TV;

#define LED_PIN_1 4
//#define RCV_READY_PIN_D5 5
#define RCV_READY_PIN_D3 3

#define DATA_LENGTH 7

volatile int8_t RCVD[20]; 
volatile byte pos = 0;; 
double rcv_data_1 = 0; 
int16_t rcv_data_2 = 0;
int16_t rcv_data_3 = 0;

unsigned long time_led_changed = 0;
boolean is_led_turned_on = false;

void setup() {
  TV.begin(NTSC,120,96);
  TV.set_vbi_hook(turnOnSPI); 
  TV.select_font(font4x6);
  TV.print(0,0, "ASCENDER DATA");

  pinMode(MISO, OUTPUT);
  pinMode(MOSI, INPUT);
  pinMode(SCK, INPUT);
  pinMode(SS, INPUT);
  pinMode(LED_PIN_1, OUTPUT);
  pinMode(RCV_READY_PIN_D3, OUTPUT);

  SPCR |= _BV(SPE); //SPI ENABLE
  SPCR &= ~_BV(MSTR); //MASTER/SLAVE SELECT
  SPCR |= _BV(SPIE); //SPI INTERRUPT ENABLE.

  SPI.setClockDivider(SPI_CLOCK_DIV16); 
  Serial.begin(9600);
}

void loop() {
  static unsigned long time_turned_on = 0;
  
  //rcv_data_1 = (double)((RCVD[3] << 24)|(RCVD[2] << 16)|(RCVD[1] << 8)|RCVD[0]);
  //rcv_data_2 = (RCVD[5]<<8)|(RCVD[4]);
  //rcv_data_3 = (RCVD[7]<<8)|(RCVD[6]);
  rcv_data_1 = *(double *)(RCVD);
  rcv_data_2 = *(int16_t *)(RCVD + 4);
  rcv_data_3 = *(int16_t *)(RCVD + 6);

  Serial.println(rcv_data_1);
  Serial.println(rcv_data_2);
  Serial.println(rcv_data_3);
  //Serial.println(pos);

  if(rcv_data_3 > 750)
  {
    //digitalWrite(LED_PIN_1, LOW); //LED_PIN : D4
    PORTD &= ~B00010000;
  }
  else if(rcv_data_3 <= 750 && rcv_data_3 >= -750)
  {
    //digitalWrite(LED_PIN_1, HIGH);
    PORTD |= B00010000;
  }
  else if(rcv_data_3 < -750)
  {
    //digitalWrite(LED_PIN_1, LOW);
    PORTD &= ~B00010000;
  }

    TV.print(0,8, "Torque : ");
    TV.print(36,8,"       ");
    TV.print(36,8,rcv_data_3); 
    TV.print(0,16,"HOOK : ");
    TV.print(32,16,"       ");
    TV.print(32,16,rcv_data_2);
    TV.print(0, 24, "GYRO : ");
    TV.print(28, 24, "               ");
    TV.print(32, 24, rcv_data_1);
}

void turnOnSPI(){
  #ifdef RCV_READY_PIN_D5
    PORTD &= ~B00100000; //PORTD : 0~7
  #endif
  #ifdef RCV_READY_PIN_D3
    PORTD &= ~B00001000;
  #endif
}

ISR(SPI_STC_vect)
{
  RCVD[pos++] = SPDR;
  if(pos > DATA_LENGTH)
  {
    RCVD[pos] = '\0';
    pos = 0;
    SPDR = 1;
  }
  else if(pos == DATA_LENGTH)
  {
    SPDR = 0;
  }
  else
  {
    SPDR = pos+1;
  }
  #ifdef RCV_READY_PIN_D5
  PORTD |= B00100000;
  #endif
  #ifdef RCV_READY_PIN_D3
  PORTD |= B00001000;
  #endif
}
@Avamander
Copy link
Owner

Avamander commented Dec 23, 2022

You are assembling your data structure in a very brittle way. The very least create a packed struct and avoid floating-point numbers. Especially if the two are both not the same architecture. After serialisation and deserialisation is done in a proper manner, eliminating those bugs, you can debug further.

@orangefabri
Copy link
Author

orangefabri commented Dec 23, 2022

my way(serialisation and deserialisation) did very well with simple SPI communication test.
but I will consider using packed struct as you said.

and I want to debug float number by TVOut because my serial port is already using.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants