DEV Community

Dimitrios Desyllas
Dimitrios Desyllas

Posted on

Why Arduino fails to receive ACK signal?

As I asked both in:

I try to initiate a data dumping from a flash memory via an ACK message vbia this python script:

import serial
from time import sleep
import base64

def ACK():
    ser.write(0x06)
    ser.write(0xD)
    ser.write(0xA)

ser = serial.Serial('/dev/ttyACM0', baudrate=9600, timeout=1)

if not ser.isOpen():
    ser.open()

print("OPEN Serial\n")
print("READ DATA\n")
while 1:
    ACK()
    line = ser.readline()
    if(line == b""): continue;
    if(line[:1] == b'2'):
        print("DATA:")
    print(line)
    print("####")

Enter fullscreen mode Exit fullscreen mode

The Arduino sketch is the following:

#define LASTBLOCK 1023
#define LASTPAGE 63
#define LASTBYTE 2111

#define PAGE_READ 0x13
#define PAGE_READ_CACHE_SEQUENCIAL 0x03
#define READ_FROM_CACHE 0x3B
#define PAGE_READ_CACHE_END 0x3F

#define PAGE_SIZE 2111 
#define BUFFER_LEN 32 

#define ACK 0x06
#define NACK 0x06


unsigned int page_to_read = 1;
unsigned int block_to_read = 1;
boolean spi_begun = false;
uint8_t bytes_index = 1;

typedef struct  {
  // Page that is transmitted
  unsigned int page;

  // Block that is transmitted
  unsigned int block;

  // A mumeric representation of the 32 byte segment that I send. 
  // I cannot send the page altogether, therefore a byte intexing is required
  uint8_t bytes_index;

  // Despite my buffer is 32 bytes the usable data may be less
  uint8_t length; 

  // Data buffer containing the data to be sent via serial
  byte data[BUFFER_LEN];
} usb_msg;


void sendMsg(usb_msg msg){
  byte* ptr = (byte*)&msg;
  Serial.print(0x02);
  for (size_t i = 0; i < sizeof(usb_msg); i++){
    Serial.print(*ptr >>4, HEX);
    Serial.print(*ptr & 0x0F, HEX);
    ptr++;
  }
  Serial.print(0x03);
  Serial.println();
}

bool clientAck()
{
  uint8_t incomingByte = NULL;
  digitalWrite(13,HIGH);
  do {
    uint8_t incomingByte = Serial.read();
  } while(incomingByte!=ACK);
  digitalWrite(13,LOW);
}

void setup() {
 Serial.begin(9600);
 pinMode(13,OUTPUT);
}

void loop() {

  // I need to reset the counts before reading any block 
  if(page_to_read > LASTPAGE){
    page_to_read = 1;
    block_to_read ++;
  }

  if(block_to_read > LASTBLOCK){
    spi_begun=false;
    return ;
  }

  if(!spi_begun){
    spi_begun=true;
  }

  clientAck();
  // Reading page there's no need for seperate function in order to avoid stack usage
  for(int bytes_to_read = PAGE_SIZE; bytes_to_read > 0; bytes_to_read-=BUFFER_LEN){
    uint8_t bytes_to_send = bytes_to_read < BUFFER_LEN ? bytes_to_read: BUFFER_LEN;
    usb_msg msg = {page_to_read, block_to_read, bytes_index, bytes_to_send, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}};
    sendMsg(msg);
    delay(100);
    bytes_index++;
  }

  page_to_read++;
  delay(100);
}
Enter fullscreen mode Exit fullscreen mode

What I try to do, is to emulate the flash memory data dumping, so I can focus on interfacing the flash memory itself in a latter step (Have to do implement it in steps).

But Arduino waits forever for ACK. Any idea why?

Discussion (0)