hallo, iedereen nog de beste wensen voor 2026
ik ben zowat het hele weekend bezig geweest, om iets voor mekaar te krijgen, wat heel simpel leek. maar toch niet bleek te zijn.
het is uiteindelijk gelukt, met behulp van onder andere chatGPT, ik weet en heb gemerkt dat het beperkingen heeft.
ik zal eerst eens een beschrijving maken van het geen wat ik wou.
- raspberry pi 5
- VS code in C
- data in lezen over USB poort
dat is "raw data", op de logic analyzer zijn het allemaal losse bytes b.v. 0xF0. in totaal 3435 bytes
- eerst de data inlezen en opslaan in een array en dan pas bewerken
- de bewerkingen zijn: data opslaan in groepjes van 15 elk groepje een apparte array.
alle 3435 bytes op splitsen in losse bits en deze opslaan in een file. (3435 x 8 = 27480) bits.
nou dat lijkt me toch niet al te ingewikkeld,......dacht ik.
het hoeft niet allemaal tegelijk, en per stuk zijn ze niet zo ingewikkeld.
het probleem waar ik tegen aan liep was dat op een of andere manier de data vaak werd geinterpeteerd als ascii.
dat kwam iedere keer terug bij het vragen in chatGPT, en bij mijn eigen testen.
dan werd 0x00 binair 0,0,1,1,0,0,0,0,0,0
dan was het o.a. voor mij onduidelijk of het geen wat in de array stond ook zo 1 op 1 werd getoond in de terminal,.....op een gegeven moment ga je aan alles twijfelen.
vraag is eigenlijk, of er niet een manier is om heel die ascii interpetatie, als het ware uit te schakelen.
het lijkt wel of ik met dat ascii gebeuren op een PC in VS code meer problemen heb als op een controller.
lijkt me ook wel logisch, ja kan met VS code op een PC ook code schrijven voor een tekst verwerkend programma waarbij veel ascii word gebruikt,
op een controller heb je dat niet, daar is mijn IDE ook microchip studio.
alvast bedankt.
SparkyGSX
Een manager is iemand die denkt dat negen vrouwen in één maand een kind kunnen maken
Ik snap helemaal niets van je vraag, er bestaat niet zoiets als "die ASCII interpretatie". Het zijn gewoon bytes, integers, binaire data, pas als jij het gaat printen naar een terminal of een string komt ASCII om de hoek. Als je binaire data direct gaat printen komt er onzin uit, print het dan als hex of zo.
Dat probleem herken ik ook niet. VS code doet dat niet vanzelf, en C/C++ ook niet. Maar er zijn wel functies om te vertalen.
Dus inderdaad, laat maar eens een stukje code zien waar het fout gaat..
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
zoals vermeld: de code werkt nu, alleen de weg er naar toe was naar mijn gevoel "omslachtig" (begreep ik niet of zo), en het zou naar mijn idee simpeler moeten kunnen.
ik zal straks de code eens posten, ik zit nu op mijn werk.
Op maandag 5 januari 2026 11:55:51 schreef Arco:
Data is data, wat die byte voorstelt hangt af van hoe je die verwerkt.
inderdaad,
maar veel is te wijten aan mijn gebrekkige programeer skils naruurlijk.
Op maandag 5 januari 2026 11:36:22 schreef SparkyGSX:
pas als jij het gaat printen naar een terminal of een string komt ASCII om de hoek
en dat stukje heb ik dus waarschijnlijk niet goed voor ogen.
Roland van Leusden
It's the rule that you live by and die for It's the one thing you can't deny Even though you don't know what the price is. It is justified.
Ik ben sinds kort ook bezig met VS code, icm de PlatformIo plugin. Gebruik jij deze ?
van watik vroeger nog weet, heb je 2 manieren om data te versturen.
ofwel als tekst (ascii) of als bin(aries). en dat moest je ook meegeven in de code.
als je binaries als tekst inleest, krijg je rare fratsen
Op maandag 5 januari 2026 12:06:02 schreef Roland van Leusden:
Ik ben sinds kort ook bezig met VS code, icm de PlatformIo plugin. Gebruik jij deze ?
nee, niet dat ik weet 
benleentje
Golden Member
In het geheugen is data altijd data en is opgeslagen als een 0 of 1.
Het is enkel de software die interpretatie doet.
Heb je audio software of video software dan doen die de data elk anders interpreteren.
Een terminal programma gaat bijna altijd uit van ascii, maar dat is enkel om er dan een woorden van te kunnen maken. Maar ook het terminal programma ontvangt gewoon data. Je kan tegen een terminal programma ook gewoon zeggen deze data is binair.
- data in lezen over USB poort
dat is "raw data", op de logic analyzer zijn het allemaal losse bytes b.v. 0xF0. in totaal 3435 bytes
Hier kan het wel heel erg mis gaan. En als je de da data van bv een arduino via serial.print naar de PC hebt gestuurd dan is je data ascii geworden. Als je RAW-data wilt gebruik dan serial.print
Wat is het verschil
Serial.print("1000"), geeft 4x een ASCII byte als 0x31, 0x30, 0x30, 0x30 of "1", "0", "0", "0"
Serial.write(1000) geeft de binaire waarde 0000 0011 1110 1000. En dat zijn 2 bytes
Ik vermoed dat het bij het verzenden via USB mis gaat en bovenstaande zijn maar 2 voorbeelden en zelfs bij het laatste kan het ook nog mis gaan om dat het eerste word aangevuld met extra nullen.
Maar aan de andere kant als je weet hoe het over de USB verstuurd word en ook als dat in ASCII is maakt niet heel veel uit, als je het maar weet.
Daarom zijn er ook zoveel protocollen voor het versturen van data. Want als je het protocol weet dan weet je ook hoe je de data moet interpreteren. En zelfs voor raw-data zijn er denk ik ook wel verschillende protocollen.
[Bericht gewijzigd door benleentje op (22%)]
fatbeard
Honourable Member
Een goed begin is geen excuus voor half werk; goed gereedschap trouwens ook niet. Niets is ooit onmogelijk voor hen die het niet hoeven te doen.
Hier kan het wel heel erg mis gaan. En als je de da data van bv een arduino via serial.print naar de PC hebt gestuurd dan is je data ascii geworden. Als je RAW-data wilt gebruik dan serial.print
... en dat doet het ook: twee keer serial.print waar duidelijk éénmaal serial.write werd bedoeeld.
Op maandag 5 januari 2026 13:43:54 schreef benleentje:
je het protocol weet dan weet je ook hoe je de data moet interpreteren
en opslaan en weergeven en bij die 2 word het "waazig"(voor mij althans) hoe dat te doen.
henri62
1-st law of Henri: De wet van behoud van ellende. 2-nd law of Henri: Ellende komt nooit alleen.
Zeer bekend issue. Afhankelijk van de mode worden CR/LF omgezet on LF's (en omgekeerd) en of XON/XOFF dingen gedaan die je niet wilt etc etc.
De poort moet je in RAW mode openen en alle line control uitschakelen, als volgt:
/* System includes */
#include <fcntl.h>
#include <stddef.h>
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
/*******************
* Local variables *
*******************/
static int fd = -1;
static struct termios old_termios;
/*
* @brief Open and initialise the UART baudrate and buffers.
*
* @note This function may open only 1 serial port at the time!
* This because the file handle and other internal state is local here.
*
* @param device The character device to open.
* @param rate The baudrate to set; use one of the supported enum values.
*
* @retval >= 0 when OK.
* @retval -1 when the serial port is already opened.
* @retval -2 when the serial port could not be opened.
*/
int uart_open(const char *device, speed_t rate)
{
if (fd != -1)
{
return -1; // Already opened.
}
fd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK | O_SYNC); // No TTY ctrl, do not block on read, write immediately
if (fd == -1)
{
return -2; // Open failed.
}
else
{
tcgetattr(fd, &old_termios);
struct termios newtio = old_termios;
cfmakeraw(&newtio); // Raw mode, line settings: n,8,1
cfsetospeed(&newtio, rate);
cfsetispeed(&newtio, rate);
tcflush(fd, TCIFLUSH);
tcdrain(fd);
tcsetattr(fd, TCSANOW, &newtio);
return fd;
}
}
/*
* @brief Close the UART, disable reception etc.
*
* @note This function may close the only serial port at the time!
*/
void uart_close(void)
{
if (fd != -1)
{
tcsetattr(fd, TCSADRAIN, &old_termios);
close(fd);
fd = -1;
}
}
device is hier het pad naar het device "/dev/ttyS0" of zoiets. Of in windows het USB path met \\.\ dacht ik, weet ik niet zeker hoe dat zat.
Op maandag 5 januari 2026 16:54:16 schreef henri62:
#include <termios.h>Of in windows het USB path met \\.\ dacht ik, weet ik niet zeker hoe dat zat.
Windows heeft geen termios library. Seriele-poort dingen portable maken tussen Unox en Windows is een ramp, kun je beter met een (ahum) Ascii-only protocol werken. En geen onderscheid maken tussen CR, CRLF of LF.
bedankt voor de reacties 
wat henri62 zegt en blurp zoek ik waarschijnlijk.
ik wou de code posten, maar dat word morgen.
ik realiseer me nu dat die code op de raspberry pi 5 staat, en die is niet "verbonden" met dropbox. dus ik kan die niet binnenhalen op mijn "woonkamer laptop" die moet ik dus met een USB stick ophalen (in de schuur), daar kom ik vandaag niet aan toe,....dat word dus morgen avond.
wel een print screen van de logic analyzer waar op de data te zien is zoals die binnenkomt in de raspberry pi 5 over de USB. allemaal 0x00 maar er komen uiteraard ook ander waardes voor.
rew
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Wat ik gok dat er kan gebeuren is dat je de tty op de raspberry pi gewoon opent en data leest.
Alle ttys op een raspberry die beginnen in "cooked" mode. Dus als je een "del" binnenkrijgt, dan gaat er het vorige teken uit de input buffer "weg". En zolang er geen "enter" komt, krijg je geen data.
Wat je wil is de tty in "raw" mode zetten.
% stty raw < /dev/ttyACM0
Vraag maar aan chatgpt om dat in je programma te integreren. Dat kan ie.
buckfast_beekeeper
Van Lambiek wordt goede geuze gemaakt.
Op maandag 5 januari 2026 17:43:58 schreef trix:
bedankt voor de reacties[...]
wel een print screen van de logic analyzer waar op de data te zien is zoals die binnenkomt in de raspberry pi 5 over de USB. allemaal 0x00 maar er komen uiteraard ook ander waardes voor.
[bijlage]
Je logic analyzer kan je instellen op ascii, binair of hex ontvangst. Als je effectief hex waardes verstuurt zal het in ascii niks leesbaar geven.
benleentje
Golden Member
Zolang de logic analyser een byte ziet maakt het niet hoe je die wegschrijft. Het is en blijft 8 bit data.
Het gaat er daarna wel om hoe je al die bytes via de USB verstuurt en of die dat echt als raw data doet
henri62
1-st law of Henri: De wet van behoud van ellende. 2-nd law of Henri: Ellende komt nooit alleen.
Op maandag 5 januari 2026 17:31:42 schreef blurp:
[...]Windows heeft geen termios library. Seriele-poort dingen portable maken tussen Unox en Windows is een ramp, kun je beter met een (ahum) Ascii-only protocol werken. En geen onderscheid maken tussen CR, CRLF of LF.
Klopt dat in windows er geen termios lib is. Daar heet het wat anders. Inderdaad serie poorten zijn wat dat betreft rampzalig. Ik heb ook afgezworen nooit vrijwillig meer iets met een COM poort in te desigen in hardware. Helemaal ziek wordt je ervan.
Maar ik zie dat het op een RPI moet runnen, dan moet die code gewoon werken onder linux.
Vergeet al die console commando's want die blijven niet "in die mode staan" als je een programma opstart.
Het enige wat echt betrouwbaar werkt is zelf al die meuk zetten met ioctl calls of de termios tcxxxx calls gebruiken.
Op het internet vind je een hele bak met allerlei varianten en overal mankeert er wel wat aan, of teveel code of te weinig, altijd wel iets wat net niet klopt. Die tc calls zijn net een zwitsers zakmes: tientallen flags en opties, de meest gekke dingen kun je aan en uit zetten. (Zie hier: https://linux.die.net/man/3/cfsetospeed)
cfmakeraw() is het ding wat er toe doet, die zet/cleared al de flags die je nodig hebt in de termios structure (zie die man page link die ik net gaf).
Dit was het kortste wat echt betrouwbaar werkt.
tty is dan iets van /dev/ttyUSB0 en baudrate B9600 bijvoorbeeld.
SparkyGSX
Een manager is iemand die denkt dat negen vrouwen in één maand een kind kunnen maken
Als ik me goed herinner kun je een com poort onder Windows gewoon openen met fopen(), in de tweede parameter kun je aangeven dat het in binaire modus moet, zodat hij niets doet met cr/lf e.d.
benleentje
Golden Member
Een microcontroller doet dit soort dingen niet en die ontvangt of stuurt gewoon letterlijk de data. De verwerking van de data mag je dan in een MCU zelf doen.
Maar de software op een PC of andere software daar weet je meestal niet precies van hoe het met de data omgaat.
nou, hier de code. grotendeels met chatgpt gegenereerd.
deze maakt o.a. een file met de raw data als hex.
en een file met de data als bits, gescheiden door "," om een CSV bestand te verkrijgen (voor latere verwerking).
het vullen v/d array Q1 t/m Q15 heb ik nog niet getest of dat goed gaat.
het aantal bytes die in de 2 files word geschreven klopt nog niet die heb ik om te testen op 1000 gezet, maar het moeten er 3435 worden.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#define TARGET_BYTES 1000 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% must be 10305
#define SCAN_LENGTH 229
// Convert a hex char to integer
int hexCharToInt(char c) {
if (c >= '0' && c <= '9') return c - '0';
if (c >= 'A' && c <= 'F') return c - 'A' + 10;
if (c >= 'a' && c <= 'f') return c - 'a' + 10;
return -1;
}
// Convert two hex chars to a byte
int hexPairToByte(char high, char low) {
int h = hexCharToInt(high);
int l = hexCharToInt(low);
if (h == -1 || l == -1) return -1;
return (h << 4) | l;
}
int main() {
unsigned char data[TARGET_BYTES];
int data_len = 0;
// --------- OPEN SERIAL PORT ---------
int serial_fd = open("/dev/ttyUSB0", O_RDONLY | O_NOCTTY | O_NONBLOCK);
if (serial_fd < 0) {
perror("Error opening /dev/ttyUSB0");
return 1;
}
struct termios tty;
memset(&tty, 0, sizeof tty);
tcgetattr(serial_fd, &tty);
cfsetospeed(&tty, B9600);
cfsetispeed(&tty, B9600);
tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8;
tty.c_cflag |= CREAD | CLOCAL;
tty.c_cflag &= ~PARENB;
tty.c_cflag &= ~CSTOPB;
tty.c_lflag = 0;
tty.c_oflag = 0;
tty.c_iflag = 0;
tty.c_cc[VMIN] = 0;
tty.c_cc[VTIME] = 0;
tcsetattr(serial_fd, TCSANOW, &tty);
// --------- OPEN OUTPUT FILES ---------
FILE *file = fopen("output.txt", "w");
FILE *binfile = fopen("binary.txt", "w");
if (!file || !binfile) {
perror("Error opening files");
return 1;
}
setvbuf(file, NULL, _IONBF, 0);
setvbuf(binfile, NULL, _IONBF, 0);
char buffer[1024];
int n;
printf("Reading ASCII hex data from /dev/ttyUSB0...\n");
// --------- READ AND PARSE HEX DATA ---------
while (data_len < TARGET_BYTES) {
n = read(serial_fd, buffer, sizeof(buffer)-1);
if (n > 0) {
buffer[n] = '\0';
char *p = buffer;
while (*p && data_len < TARGET_BYTES) {
if (*p == ' ') { p++; continue; }
if (*(p+1)) {
int byte = hexPairToByte(*p, *(p+1));
if (byte != -1) {
data[data_len++] = (unsigned char)byte;
fprintf(file, "0x%02X ", byte);
}
p += 2;
} else break;
}
fflush(file);
}
else
{
// -------- no data available, wait a bit --------
usleep(1000); // wait 1 ms before trying again
}
}
printf("DDDD\n"); //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
close(serial_fd);
fclose(file);
printf("ASCII hex data saved to output.txt\n");
// --------- WRITE BINARY FILE ---------
for (int i = 0; i < data_len; i++) {
for (int b = 7; b >= 0; b--) {
fprintf(binfile, "%d", (data[i] >> b) & 1);
if (!(i == data_len - 1 && b == 0)) fprintf(binfile, ",");
}
}
fclose(binfile);
printf("Binary data saved to binary.txt\n");
// --------- SPLIT DATA INTO Q1-Q15 ---------
int Q1[SCAN_LENGTH], Q2[SCAN_LENGTH], Q3[SCAN_LENGTH], Q4[SCAN_LENGTH], Q5[SCAN_LENGTH];
int Q6[SCAN_LENGTH], Q7[SCAN_LENGTH], Q8[SCAN_LENGTH], Q9[SCAN_LENGTH], Q10[SCAN_LENGTH];
int Q11[SCAN_LENGTH], Q12[SCAN_LENGTH], Q13[SCAN_LENGTH], Q14[SCAN_LENGTH], Q15[SCAN_LENGTH];
for (int i = 0; i < SCAN_LENGTH; i++) {
Q1[i] = data[i + 0 * SCAN_LENGTH];
Q2[i] = data[i + 1 * SCAN_LENGTH];
Q3[i] = data[i + 2 * SCAN_LENGTH];
Q4[i] = data[i + 3 * SCAN_LENGTH];
Q5[i] = data[i + 4 * SCAN_LENGTH];
Q6[i] = data[i + 5 * SCAN_LENGTH];
Q7[i] = data[i + 6 * SCAN_LENGTH];
Q8[i] = data[i + 7 * SCAN_LENGTH];
Q9[i] = data[i + 8 * SCAN_LENGTH];
Q10[i] = data[i + 9 * SCAN_LENGTH];
Q11[i] = data[i + 10 * SCAN_LENGTH];
Q12[i] = data[i + 11 * SCAN_LENGTH];
Q13[i] = data[i + 12 * SCAN_LENGTH];
Q14[i] = data[i + 13 * SCAN_LENGTH];
Q15[i] = data[i + 14 * SCAN_LENGTH];
}
printf("Data split into Q1-Q15 successfully.\n");
return 0;
}
Als dit werkt -zoals je zegt- dan wordt de oorspronkelijke data als ASCII verzonden. Dus dan zit er een conversie naar ASCII in de controller die de data verstuurt.
Heb je daar ook code van?
henri62
1-st law of Henri: De wet van behoud van ellende. 2-nd law of Henri: Ellende komt nooit alleen.
struct termios tty;
memset(&tty, 0, sizeof tty);
tcgetattr(serial_fd, &tty);
cfsetospeed(&tty, B9600);
cfsetispeed(&tty, B9600);
tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8;
tty.c_cflag |= CREAD | CLOCAL;
tty.c_cflag &= ~PARENB;
tty.c_cflag &= ~CSTOPB;
tty.c_lflag = 0;
tty.c_oflag = 0;
tty.c_iflag = 0;
tty.c_cc[VMIN] = 0;
tty.c_cc[VTIME] = 0;
tcsetattr(serial_fd, TCSANOW, &tty);
doet (ongeveer) hetzelfde als dit:
tcgetattr(fd, &old_termios);
struct termios newtio = old_termios;
cfmakeraw(&newtio); // Raw mode, line settings: n,8,1
cfsetospeed(&newtio, rate);
cfsetispeed(&newtio, rate);
tcflush(fd, TCIFLUSH);
tcdrain(fd);
tcsetattr(fd, TCSANOW, &newtio);
Wat veel korter is (zelfs met restore en flush) en overzichtelijker.
Het probleem dit denk ik bij jouw in die c_#flags meuk waar iets ontbreekt.
Als die zooi eruit kieperen en cfmakeraw() gebruiken.