DEV Community

Dimitrios Desyllas
Dimitrios Desyllas

Posted on

3 2

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?

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more

Top comments (0)

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more