Запись на SD карту потока бинарных данных при меняющемся размере информации.
- Войдите на сайт для отправки комментариев
Дело в следующем. Есть Arduino, к нему подключен датчик, выдающий бинарные сообщения и необходимо эти данные записывать неразрывано на SD карту. Ниже показан правильно записанный файл. Сначала идет преамбула (64 бита), потом номер сообщения (16 бит), далее идет количество 32 битных слов (16 бит), потом сами 32-х битные слова и замыкает все дело чексумма.
Смысл заключается в следующем: Т.к преамбула идет первой, то можно пропустить первые 64+16 бит и перейти сразу к числу сообщений. Находим это число, при этом нужно понимать, что порядок следования байт – little-endian (младший байт идет первым), а значит нужно как-то это правильно считать... Нашли что это за число, допустим в примере это 8, значит 8 - 32х битных сообщений + чексумма 32 бита. Считаем общее количество и записываем на SD карту. При этом нужно будет записать идущую вначале приамбулу и номер сообщения, значит их запись нужно начинать в самом начале, потом вычислять оставшуюся длинну сообщения и дозаписывать ее и так по циклу (Запись: преамбула + номер сообщения + оставшееся кол-во бит).
На данном этапе запись осуществляется совсем не по такому плану, т.к я новичок и не знаю как осуществить задуманное...
Вот код который есть на данном этапе.
С помощью него можно просто писать на карту определенное количество информации, но при таком виде много пакетов битых.
#include <SD.h> #include <SPI.h> /* --- Defines --- */ #define USBrate 115200 // USB-COM baud rate (speed) #define mySerial Serial1 // UART for GPS #define UARTrate 115200 // GPS UART baud rate (speed) #define myFile "GPSLOG00.TXT" // Log File name #define GPSECHO true // Set the pins used #define chipSelect 10 #define ledPin 13 byte rx_byte; File dataFile; /*--- Program ---*/ // blink out an error code void error(uint8_t errno) { while(1) { uint8_t i; for (i=0; i<errno; i++) { digitalWrite(ledPin, HIGH); delay(100); digitalWrite(ledPin, LOW); delay(100); } for (i=errno; i<10; i++) { delay(200); } } } void setup() { // connect at 115200 so we can read the GPS fast enough and echo without dropping chars // also spit it out Serial.begin(USBrate); Serial.println("\r\nUltimate GPSlogger Shield"); pinMode(ledPin, OUTPUT); // make sure that the default chip select pin is set to // output, even if you don't use it: pinMode(10, OUTPUT); // see if the card is present and can be initialized: //if (!SD.begin(chipSelect, 11, 12, 13)) { if (!SD.begin(chipSelect)) { // if you're using an UNO, you can use this line instead Serial.println("Card init. failed!"); error(2); } char filename[15]; strcpy(filename, myFile); for (uint8_t i = 0; i < 100; i++) { filename[6] = '0' + i/10; filename[7] = '0' + i%10; // create if does not exist, do not open existing, write, sync after write if (! SD.exists(filename)) { break; } } dataFile = SD.open(filename, FILE_WRITE); if( ! dataFile ) { Serial.print("Couldnt create "); Serial.println(filename); error(3); } Serial.print("Writing to "); Serial.println(filename); // connect to the GPS at the desired rate mySerial.begin(UARTrate); Serial.println("Ready!"); } void loop() { // отправляем данные только после их получения: if (mySerial.available()) { rx_byte = mySerial.read(); //Записываем данные в файл byte data[10000]; dataFile.write(data,mySerial.readBytes((byte*)data,sizeof(data))); //dataFile.write(data,sizeof(data)); dataFile.flush(); if (GPSECHO) if (rx_byte) Serial.print(rx_byte, HEX); } }
А вот byte data[10000]; - это щедрость или транжирство? Контроллер какой?
Arduino Due контроллер. Я даже 20 000 ставил, нормально, прет)
Кстати есть непонятка.
if
(rx_byte)
Serial
.print(rx_byte, HEX);
Эта строка выдает мне по 2 символа между записью на карту вроде как. Я думаю, что это потерянная информация, так ли это?
Так понять из Вашего поста вобще мало чего можна. Опишите протокол. У Вас завершение приема по таймауту шоле? И скоко, где задается? Потому как по коду получается так, если шото принято (все-не все ХЗ но скорей всего, только первые байты) , то читае rx_byte затем читаем все что есть до таймаута (судя по предку stream.readBytes а скоко таймаут опять ХЗ, и вообще оно так работает? я не пробовал использовать контроль таймаута от stream) и это пишем на карту, а rx_byte не пишем, но выводим в ответ.
Так понять из Вашего поста вобще мало чего можна. Опишите протокол. У Вас завершение приема по таймауту шоле? И скоко, где задается? Потому как по коду получается так, если шото принято (все-не все ХЗ) , то читае rx_byte затем читаем все что есть до таймаута (судя по предку stream.readBytes а скоко таймаут опять ХЗ, и вообще оно так работает? я не пробовал использовать контроль таймаута от stream) и это пишем на карту, а rx_byte не пишем, но выводим в ответ.
Завершение - это когда я USB вытаскиваю из компьютера) Завершение пока не предусмотрено, но пишется все с помощью dataFile.flush();
Мне необходимо чтобы байты считывались и анализировались, как я выше описал, сейчас этот алгоритм не подходит, действует как бревно вместо лодки.
Ну както одно сообщение от другого должно отделятся, или все сплошняком пишется? Тогда и rx_byte наверно нужно тоже того. Записать. Чексума выше упоминаемая предполагает разделение на сообщения, она для каждого считается. Тогда как разделять?
Ну както одно сообщение от другого должно отделятся, или все сплошняком пишется? Тогда и rx_byte наверно нужно тоже того. Записать. Чексума выше упоминаемая предполагает разделение на сообщения, она для каждого считается. Тогда как разделять?
Каждое новое сообщение начинается с преамбулы и завершается чексуммой. А между ними есть еще 32х битные данные, которых N-е количество и всегда разное. Выше я все расписал.
Суть такова, что нужно записать полностью все, без разрывов. Пока у меня не получается.
Вот так это делается в программе DELPHI. и все работает.
Обратите внимание на Count в делфовском коде, если оно известно то и ардуино пишите совершенно аналогично. Цикл, байт приняли - байт записали. Единственное что в делфи ReadBuf блокирующий, а в ардуине mySerial.read(); неблокирующий. Но mySerial.available() позволит проврить есть ли принятые данные и сколько их есть и можно подождать если их нет. Просто надо решить, что делать если данные ещё пока не приняты: тупо ждем следующий байт, выполняем скетч дальше (если вобще есть что делать). Пример для второго варианта, похожего приема из моего рабочего проекта. Принимает LenRecive байт с проверкой чексумы. Из основног лупа она переодически дергается пока возвращает RECIVE_PROCESS, это значить пока не принято все.
Не совсем понимаю что делает ваш код. Как его применить для моего случая с записью на SD?
Не совсем понимаю что делает ваш код. Как его применить для моего случая с записью на SD?
Достаточно вдумчиво прочитать и проверить свое представления о действии функций. Код принимает LenRecive байт в буфер и еще одного CRC. При этом учитывается тот факт, что на момент вызова этой функции может быть принято еще не все сообщение.
Не совсем понимаю что делает ваш код. Как его применить для моего случая с записью на SD?
Достаточно вдумчиво прочитать и проверить свое представления о действии функций. Код принимает LenRecive байт в буфер и еще одного CRC. При этом учитывается тот факт, что на момент вызова этой функции может быть принято еще не все сообщение.
Можно увидеть полностью код? С описанием переменных и какие библиотеки подключались
там здоровенный проект, экран, сервомашинка, линейный привод, датчик температуры и т.д. 2 ардуины общаются и 99% кода совсем не по теме. Это один из методов класса протокола обмена. Чисто как пример, а вызовы выглядят дето так.
Обратите внимание на общий подход. Все без циклов ожидания, луп крутится максимально быстро, для микроконтролеров это правильно.
Давайте лучше про Ваши проблемы. Код у Вас похож на правду, пропуски данных будут из за несохранения в файл считаного
Serial
.read
, оно потом в буфере уже не присутствует. Это если код - аналог дельфовского. Если чего больше то тоже не проблема.там здоровенный проект, экран, сервомашинка, линейный привод, датчик температуры и т.д. 2 ардуины общаются и 99% кода совсем не по теме. Это один из методов класса протокола обмена. Чисто как пример, а вызовы выглядят дето так.
Обратите внимание на общий подход. Все без циклов ожидания, луп крутится максимально быстро, для микроконтролеров это правильно.
Давайте лучше про Ваши проблемы. Код у Вас похож на правду, пропуски данных будут из за несохранения в файл считаного
Serial
.read
, оно потом в буфере уже не присутствует. Это если код - аналог дельфовского. Если чего больше то тоже не проблема.Вообщем, пока я не понял как сделать так, чтобы ничего не терялось. И не понятно, поможет ли то, если я буду знать длинну сообщения, ведь все равно будет потом запись на карту и данные начнут теряться, мне кажется. Тут следует сделать, что-то хитрое. 2й или 3й буфер, но т.к я новичок, я не знаю как это сделать. Буду признателен, если вы мне поможете откорректировать мой код.
С праздником Пасхи вас!
Кстати говоря, меня бы вполне устроило, если бы сообщения записывались полностью по такому сценарию. (Тут возможны пропуски потока данных, но они будут минимально влиять).
Значит так, нужно сделать терминатор, который будет отслеживать по потоку данных Преамбулу (она имеет известный набор данных). И когда он находит преамбулу, то сразу начинает писать с нее данные, когда начинается следующая преамбула, он заканчивает запись в буфер и идет запись на карту. И так по циклу - нашел 1 преамбулу - запись до следующей приамбулы в буфер и потом на карту. Получается он будет пропускать некоторые сообщения возможно, но зато они будут целыми.
Как так сделать, поможете?
И Вас с праздниками.
\\\\Значит так, нужно сделать терминатор, который будет отслеживать....
Вполне можно, хотя и громоздко будет отслеживать. Надо будет искать вхождение преамбулы в входящее сообщение. Так делают, но обычно исчут короткий кусок, несколько байт. Вы тоже можете так сделать, ищете первые допустим 4 байта, если нашли - либо "верите" и отсчитываете длину оставшегося до сообщения и пропускаете, либо "проверяете" т.е. принимаете и сверяете остальное. В любом случае дальше сообщение, его сохраняете, если длина известна, я так понял у Вас она определяема по сообщению, то лучше/проще конец сообщения ловить по длине.
Вы пока поймите, что у Вас скорей всего нет проблемы с записю на карту.
Есть проблема приема с порта, и она похоже из-за неправильного представления о работе mySerial.read(); и mySerial.readBytes.
Если что прочитано mySerial.read(); то оно из приемного буфера удаляется и mySerial.readBytes его уже не прочитает. Отсюда пропуски.
И Вас с праздниками.
\\\\Значит так, нужно сделать терминатор, который будет отслеживать....
Вполне можно, хотя и громоздко будет отслеживать. Надо будет искать вхождение преамбулы в входящее сообщение. Так делают, но обычно исчут короткий кусок, несколько байт. Вы тоже можете так сделать, ищете первые допустим 4 байта, если нашли - либо "верите" и отсчитываете длину оставшегося до сообщения и пропускаете, либо "проверяете" т.е. принимаете и сверяете остальное. В любом случае дальше сообщение, его сохраняете, если длина известна, я так понял у Вас она определяема по сообщению, то лучше/проще конец сообщения ловить по длине.
Вы пока поймите, что у Вас скорей всего нет проблемы с записю на карту.
Есть проблема приема с порта, и она похоже из-за неправильного представления о работе mySerial.read(); и mySerial.readBytes.
Если что прочитано mySerial.read(); то оно из приемного буфера удаляется и mySerial.readBytes его уже не прочитает. Отсюда пропуски.
Т.е мне нужно просто убрать ненужные: mySerial.read(); и все будет ок?
Просто это реально не нужные строки, я думал они не мешают.
Должно быть. Пробуйте! И сюда отпишите.
Должно быть. Пробуйте! И сюда отпишите.
Да, все хорошо пишется теперь без потерь)))))) Но, этого мало, т.к когда я выключаю запись у меня обрывается все на половине сообщения и я не могу сразу работать с таким файлом.....
Теперь нужно чтобы сообщения писались не по фиксированному буферу, а по плавающему. Т.е нужно знать длину сообщения. Ее можно узнать из самого сообщения, это первые 16 бит после преамбулы (с учетом того, что младший байт первый). Порядок следования байт – little-endian (младший байт идет первым).
Вообщем структура сообщения такая:
<преамбула: 64>< ndat & ncmd: 32><dat1, dat2,......datN><сs: 32>
<преамбула: 64>: преамбула “GEOSr3PS” (64 бита, 534F4547 53503372)
<ndat> : количество 32-ти разрядных слов данных содержательной части сообщения (16 бит)
<ncmd> : номер сообщения (16 бит)
<dat1, dat2,......datN>: содержательная часть сообщения (32-х битные слова); количество данных соответствует параметру ndat
<сs>: контрольная сумма сообщения (32 бита); вычисляется как «исключающее ИЛИ» по всем полям сообщения, представленным в виде 32-х битных слов.
Я думаю нужно добавить еще несколько массивов (например) Mas[16] Mas[32] ну и тд и можно будет с ними уже оперировать и узнать необходимый кусок - ndat (16 первых бит, который отвечает за длину конкретного сообщения). Пока нужно получить этот кусок, дальше, когда получим, нужно все куски сложить и получить полную длину сообщения, ее и нужно вбивать в буфер, который уже будет знать полную длину сообщения и сохранять все как нада.
Рано радовался, где-то чето теряется все же.....
А чего Вы в битах оперируете, этоже мазохизм;)) Считайте в байтах, так проще. Можна несколько массивов, можна и в одном. Его даже можна заполнять не с первого елемента, а с произвольного и не до конца, а как хочется. Это чисто как Вам видится удобней. Можна даже переменные совать в mySerial.readBytes например int R; mySerial.readBytes((byte*)&R, sizeof(R)) заполнит переменную. Причем такая форма годится для любого типа R. Профи часто делают так, описывают протокол в виде структуры и подсовывают указатель на такую структуру в функции типа readBytes. И вуаля! Структура автоматом заполнена, все разложено как положено, а описание структуры уже намек на документацию))) Может я и напрасно расказываю, это сложновато для новичка, но вдруг...
А чего Вы в битах оперируете, этоже мазохизм;)) Считайте в байтах, так проще. Можна несколько массивов, можна и в одном. Его даже можна заполнять не с первого елемента, а с произвольного и не до конца, а как хочется. Это чисто как Вам видится удобней. Можна даже переменные совать в mySerial.readBytes например int R; mySerial.readBytes((byte*)&R, sizeof(R)) заполнит переменную. Причем такая форма годится для любого типа R. Профи часто делают так, описывают протокол в виде структуры и подсовывают указатель на такую структуру в функции типа readBytes. И вуаля! Структура автоматом заполнена, все разложено как положено, а описание структуры уже намек на документацию))) Может я и напрасно расказываю, это сложновато для новичка, но вдруг...
Это долго переделать мой код? А то я мог бы попробовать сразу, протестировать.... чето уже больше 2х недель бьюсь об камень)
Так там толком переделывать нечего, десять строк с 92 по 102. Закоментируйте, авось пригодится, вытереть всегда успеете и начинайте писать. Заливайте, проверяйте, сюда выкладуйте, там все очень просто.
Так там толком переделывать нечего, десять строк с 92 по 102. Закоментируйте, авось пригодится, вытереть всегда успеете и начинайте писать. Заливайте, проверяйте, сюда выкладуйте, там все очень просто.
Мне не просто) Это моя первая программа и я вообще не бум бум в программировании на C++. Может быть вы поможете, раз там все просто?
Я вот подумал, может мне сгодиться вот этот код? http://arduino.ru/forum/programmirovanie/peredacha-izobrazheniya-s-arduino-na-kompyuter-cherez-serial
А еще мне кажется у меня вот такая проблема: http://pashkevich.me/article/6.html
Подводный камень:
Функция "не отчищает" тот массив в который складывает переданные байты, отсюда возникают ситуации наподобие следующей.
Вы передали строку "Hi max" она состоит ровно из 6 байт, и каждый байт последовательно будет размещен в массиве с самого начала и на мониторе вы получили "Hi max"
Далее, вы передали строку "Hello" эта строка занимает лишь 5 байт, и будет записана в ваш массив с самого начала в результата на мониторе вы получите "Hellox".
Лишняя буква "X" это остаток от предыдущей строки, то есть если вы не запишите все 6 байт или в программе не отчистите массив то при передачи блока меньшего размера вы получите остатки и от старого более длинного блока который хранится в вашем массиве от предыдущего вызова функции.
Функция "не отчищает" тот массив в который складывает переданные байты,
Бывает. Эта проблема больше для строк, чем для двоичных данных. Помните, что mySerial.available() возвращает количество реально принятых байт. Используйте это значение при извлечении из буфера и в прочих случаях. Например, если принято 6 и более байт то извлечем их - byte L=mySerial.available(); if(L>=6) mySerial.readBytes(buf, L); Этот код можно крутить в лупе и он будет ждать момента, когда поступит 6 и более байт.
Функция "не отчищает" тот массив в который складывает переданные байты,
Бывает. Эта проблема больше для строк, чем для двоичных данных. Помните, что mySerial.available() возвращает количество реально принятых байт. Используйте это значение при извлечении из буфера и в прочих случаях. Например, если принято 6 и более байт то извлечем их - byte L=mySerial.available(); if(L>=6) mySerial.readBytes(buf, L); Этот код можно крутить в лупе и он будет ждать момента, когда поступит 6 и более байт.
Да, это понятно, но тут вопрос в другом.... Мне все же нужно точно знать сколько байт придет чтобы буфер был ровно под то количество байт, что приходит.... А этот размер можно узнать только прочитав начало каждого сообщения и вычленив из него нужные байты. Но дело в том, как это сделать, причем нужно иметь ввиду, что начало сообщения тоже нужно будет записать.
В приницпе мы точно знаем сколько начало весит, это 8 + 2 байта +2 байта - это количество дальнейшей инфы. Их наверно нужно в массив:
byte preambula[12];
byte kolichestvo[10];
Показуйте ошибки. Пока вижу byte ostatok[C*4+4]; Тут переменная недопустима, только константы. Кстати А,В и С не обявлены, тоже плохо. Надо по С немного почитать, например вот http://dfe.petrsu.ru/koi/posob/c/c.htm первое попавшее из гугла, но вроде неплохо и кратко. Про типы данных, переменные. Это основы без них тяжело.
Массив переменной длины в принципе возможен, но там нада память распределять освобождать... Пока Вам оно не надо.
Обявляйте массив по максимально допустимому размеру, а используйте только часть нужную. Т.е. byte ostatok[10000];D = dataFile.write(data,mySerial.readBytes((byte*)ostatok,C*4+4)); Ну из предположения что С правильно посчитано и арифметика вокруг него та.
\\\\НО как я написал это будет работать только с началом...
Так после данных, длина которых переменна, снова идет преамбула? Тогда цикл, программа же уже знает, что делать с преамбулой. Новую преамбулу читаем на место старой и т. д.
Показуйте ошибки. Пока вижу byte ostatok[C*4+4]; Тут переменная недопустима, только константы. Кстати А,В и С не обявлены, тоже плохо. Надо по С немного почитать, например вот http://dfe.petrsu.ru/koi/posob/c/c.htm первое попавшее из гугла, но вроде неплохо и кратко. Про типы данных, переменные. Это основы без них тяжело.
Массив переменной длины в принципе возможен, но там нада память распределять освобождать... Пока Вам оно не надо.
Обявляйте массив по максимально допустимому размеру, а используйте только часть нужную. Т.е. byte ostatok[10000];D = dataFile.write(data,mySerial.readBytes((byte*)ostatok,C*4+4)); Ну из предположения что С правильно посчитано и арифметика вокруг него та.
\\\\НО как я написал это будет работать только с началом...
Так после данных, длина которых переменна, снова идет преамбула? Тогда цикл, программа же уже знает, что делать с преамбулой. Новую преамбулу читаем на место старой и т. д.
Да, после данных с переменной длинной снова идет преамбула. Получается после того, как все считается полностью, то массив очищается и снова будет новый?
Кстати как быть с тем, что порядок следования байт – little-endian (младший байт идет первым)? Можно ли сразу это объявить глобально как-то? а то получится не верное считывание числа. Ну или считать число, указывающее "количество 4 байтовыйх сообщений" и его сконвертировать уже в little-endian, можно так?
Показуйте ошибки. Пока вижу byte ostatok[C*4+4]; Тут переменная недопустима, только константы. Кстати А,В и С не обявлены, тоже плохо. Надо по С немного почитать, например вот http://dfe.petrsu.ru/koi/posob/c/c.htm первое попавшее из гугла, но вроде неплохо и кратко. Про типы данных, переменные. Это основы без них тяжело.
Массив переменной длины в принципе возможен, но там нада память распределять освобождать... Пока Вам оно не надо.
Обявляйте массив по максимально допустимому размеру, а используйте только часть нужную. Т.е. byte ostatok[10000];D = dataFile.write(data,mySerial.readBytes((byte*)ostatok,C*4+4)); Ну из предположения что С правильно посчитано и арифметика вокруг него та.
\\\\НО как я написал это будет работать только с началом...
Так после данных, длина которых переменна, снова идет преамбула? Тогда цикл, программа же уже знает, что делать с преамбулой. Новую преамбулу читаем на место старой и т. д.
Кстати моя ошибка в том, что у меня написано так, что ниче не заработает, потому что написано куча записей и одна другую перекрывает, как мне кажется.
Получается после того, как все считается полностью, то массив очищается и снова будет новый?
Массив, он как и любая другая переменная, после обявления просто есть. Заполняется, извлекается и т.д. на факт его существования не сказывается. Он как ведро, шоле. Воду наливай, выливай, ведро остается. И статически обявленный масив есть пока есть программа, и как новый.
Кстати как быть с тем, что порядок следования байт – little-endian (младший байт идет первым)? ...
Не проблема. Если порядок следования байт не тот (сразу твердо даже не вспомню как оно, у разных процессоров разное) то их завсегда можно переставить ручками типа byte a=buf[5];buf[5]=buf[6];buf[6]=a; и два байта переставили. Четыре аналогично.
Получается после того, как все считается полностью, то массив очищается и снова будет новый?
Массив, он как и любая другая переменная, после обявления просто есть. Заполняется, извлекается и т.д. на факт его существования не сказывается. Он как ведро, шоле. Воду наливай, выливай, ведро остается. И статически обявленный масив есть пока есть программа, и как новый.
Кстати как быть с тем, что порядок следования байт – little-endian (младший байт идет первым)? ...
Не проблема. Если порядок следования байт не тот (сразу твердо даже не вспомню как оно, у разных процессоров разное) то их завсегда можно переставить ручками типа byte a=buf[5];buf[5]=buf[6];buf[6]=a; и два байта переставили. Четыре аналогично.
Может кто-нибудь всю программу написать за 500 рублей? Это ведь легко, кто владеет языком С++. Да и руководство к протоколу, что нужно писать, имеется.
Так Вы в раздел http://arduino.ru/forumy/ishchu-ispolnitelya напишите, там изголодавшиеся токо и ждут ;)
Датчик самостоятельно без запроса кидает данные? А в общем, если свзяь устойчивая и без ошибок, то пиши по прерыванию прихода байта сразу в файл. )))
Датчик самостоятельно без запроса кидает данные? А в общем, если свзяь устойчивая и без ошибок, то пиши по прерыванию прихода байта сразу в файл. )))
Да, датчик самостоятельно кидает данные. По прирыванию это как, не очень понимаю?
По прирыванию это как, не очень понимаю?
И правильно, не надо такое понимать, он шутит, из прерывания писать на карту слишком долго, а обработчик должен быть коротким как выстрел.
По прирыванию это как, не очень понимаю?
И правильно, не надо такое понимать, он шутит, из прерывания писать на карту слишком долго, а обработчик должен быть коротким как выстрел.
Мне один человек ответил вот что по моему коду:
Я его залил:
и получил следующие ошибки:
1. error: 'size' does not name a type. size=&buff[8];
2. error: 'read' was not declared in this scope: mySerial.readBytes(ptr,read=10);
3. error: invalid operands of types 'int*' and 'int' to binary 'operator*' mySerial.readBytes(ptr,size*4+4);
4. error: invalid operands of types 'int*' and 'int' to binary 'operator*'. read+=size*4+4;
5. error: invalid operands of types 'int*' and 'int' to binary 'operator*'. if(read>8+2+2+size*4+4)
6. error: 'buf' was not declared in this scope.
7. error: 'testcrc' was not declared in this scope.
8. error: invalid operands of types 'int*' and 'int' to binary 'operator*'. dataFile.write(buf,8+2+2+size*4+4);
9. 'size' does not name a type
Ага. Характерно для впервые компилируемого кода. Восновном вокруг size которая то указатель то значение. Для 3-5 и 8 замените size на (*size), read обявите...
Но если это за деньги - пихните ему обратно.
Ага. Характерно для впервые компилируемого кода. Восновном вокруг size которая то указатель то значение. Для 3-5 и 8 замените size на (*size), read обявите...
Но если это за деньги - пихните ему обратно.
Сделал, теперь не пойму как объявить size или куда может ее в другое место нужно поставить?
Ага. Характерно для впервые компилируемого кода. Восновном вокруг size которая то указатель то значение. Для 3-5 и 8 замените size на (*size), read обявите...
Но если это за деньги - пихните ему обратно.
Вряд ли это за деньги))))) это же не готовая программа.
Пока ничего не выходит, объявлял переменные как Byte.
Строка size=&buff[8]; точно должна быть там где она есть? Вообщем новые ошибки.
И правильно, не надо такое понимать, он шутит, из прерывания писать на карту слишком долго, а обработчик должен быть коротким как выстрел.
Та я как-бы не то чтобы шучу, а намекаю на первоочередный вопрос, с какой скоростью сыпятся данные? Может там 100 Мбит, и ни какой алгоритм не поможет.
А насчет долго, то вроде дуе это уже арм, работающий на 84 Мгц. Так что ничего не долго, можно самому создать файл в свободных секторах и писать напрямую, есть фича такая у карточек - автоматом переходят на следующий сектор (write block называется).
Скорость в первом сообщении, 115200, откуда по ЮСБ быть 100М. А долго не потому что проц плох, а потому что на карту по SPI всегда долго. А в файловую систему - так вобще трындец. Но Вы правы что момент скорости требует внимания.
можно самому создать файл в свободных секторах и писать напрямую, есть фича такая у карточек - автоматом переходят на следующий сектор (write block называется).
А вот это - грязный хак. Тут или/или надо. Или работать через ФС и использовать её преимущества и отгребать недостатки, или свой формат карты и забыть о совместимости. Каждый подход имеет право на жизнь. Но смешивать нельзя, проблем масса будет.
Мне скорректировали предыдущий код:
Теперь только ошибка
Подниму тему. Никто не знает как исправить эти ошибки?
у arduino little-endian порядок
соответственно
byte buff[2]={2,0};
int *a=(int*)buff;
в переменной *a будет 2, а не 512
Ее нужно поправить
Верно, реализации функции не хватает
Даже без testcrc никакие данные не записываются и мало того, не передаются
+ к тому, size показывает заоблочное число, например: 124539593 - а это явно не число 32 битных сообщений
Никто не поможет?
Кто знает, как написать проверку вначале, чтобы проверялось на наличие передающейся преамбулы, а потом если она передалась, то начать какое-то действие.
+ к тому, size показывает заоблочное число, например: 124539593 - а это явно не число 32 битных сообщений
Никто не поможет?
А у вас и не число 32 битное. Это указатель на int. 2 байта. И соответственно ни как не 124539593.
Все сильно напутано.