sprintf causing timing-issues? - arduino

I'm experiencing a perculiar issue when using sprintf.
I need a char array to look like this: g;cmd;arg;e;, where arg gets leading zeros so it is always 3 chars long, and cmd gets leading zeros so it's always 15 chars long.
As an example, if cmd = 20 and arg = 3749, I need a char array looking like this: g;020;000000000003749;e;.
Both arg and cmd are integers.
I initially accomplished this in pretty inefficient way, but I changed it to something much simpler using sprintf because I needed my code to be faster. Both my initial code and my change can be found on github.
My current implementation looks like this:
#define cmdMsgLength 3
#define argMsgLength 15
#define totalFormatedMsgLength (2+cmdMsgLength+1+argMsgLength+3)
#define msgFormater "g;%03d;%015d;e;"
char msgToSendFormated[totalFormatedMsgLength];
void sendMsg(int _cmd, int _arg) {
sprintf(msgToSendFormated, msgFormater, _cmd, _arg);
Serial.print(msgToSendFormated);
}
This seemed to work well, until my uC also had to control 4 ESC's. I honestly can't find any relation between the two, but it seems like this implementation leads to problems with the ESC's, where of course timing is quite important. The ESC's are being programmed correctly, but when using the Arduino function servo.writeMicroseconds to actuate them, they seem to act randomly. After quite a lot of tests, only this change to my code seems to be causing the issue. As this piece code is so simple and the old code (check the github link) also used Serial.print, I assume sprintf is the culprit.
Is sprintf known to cause these sort of timing-issues? Could it be anything else?

As JVApen pointed out, sprintf always writes a null terminator. As msgToSendFormated was not long enough for that, I'd get an overflow. Setting char msgToSendFormated[totalFormatedMsgLength + 1]; fixed the problem.

Related

I need help for gamemaker 2.3

Pls help me
A few weeks ago it came out of gamemaker 2.3, practically in the gamemaker language they changed the scripts into functions, but now after converting the files to be able to reopen them, I double-checked all the scripts and etc but anyway when I start it it remains a black screen, however it doesn't give me any compilation errors or whatever, what could be the problem?
Ps.
I might sound stupid, but if someone has the same program as me I can pass the project to them so they can see the scripts for themselves, so basically it's just the base and there is only the script to make the player walk and for collisions, I know that no one would want to waste time, but I ask the same
Its possible that your code is stuck in an infinite loop, here's an example of what that might look like:
var doloop = true
while(doloop == true){
x += 1
y += 1
}
the "doloop" variable is never changed within the while loop, so it is always equal to true and the loop never ends. Because the code never finishes looping, it can never get around to drawing anything, so you end up with a black screen. The easiest way to check for these is to put a breakpoint/debugging point at the beginning and just after every while/for/do/ect loop and debug it. e.g. (I am using asterisks "*" to represent breakpoints)
var doloop = true
* while(doloop == true){
x += 1
y += 1
}
*
When you get to one of the loops remove the first breakpoint and hit the "continue" button in the debugger. If it (it being the computer) takes an longer than it should to hit the second breakpoint (as in, you wait for a ten seconds to or two minutes (depends on how complex the code is) and it still hasn't hit the second breakpoint), then you should replace the breakpoint at the beginning of the loop to check and make sure it is still in there. If it is still in the loop, then that is likely where the code is getting stuck. Review the loop and everywhere any associated variables are set/changed, and you should be able to find the problem (even if it takes a while).
Majestic_Monkey_ and the commentors are correct: use the debugger. It's easy and it's your friend. Just place a red circle on the very first line of code that runs, and click the little bug icon and you can step through your code easily.
But to address your specific issue (or if anyone in the future has this issue): scripts have changed into files that can have many functions. Where you used to have
//script_name
var num = argument0 + argument1;
return num;
You would now have
function script_name(a, b) {
var num = a + b;
return num;
}
All you have to do is create a decleration for your new function:
function my_function_name(argument_names, etc...)
Then wrap all your old code in { }, and replace all those ugly "argument0" things with actual names. It's that easy. Plus you can have more than one function per script!

Arduino program code in .data

It seems as though some of my functions are being placed into the .data section. This is for a library that has classes.
I've looked at the memory map as suggested here:
http://www.nongnu.org/avr-libc/user-manual/group_demo_project.html
I've also been using avr-size to see the size of the .data and .text questions.
Any ideas why the program code is getting placed in .data and not .text?
I think I figured out what was happening.
It only looked like code was going into the .data section. What was actually going in there were the char * from debug messages and thus taking up large fractions of space.
For example, I had a bunch of Serial.println("debug message that is a long string."); An easy way around this for Serial.println is the use of the F() macro, which stores the string in FLASH instead of RAM (.data section I was seeing).
Also, this link provides some good info on memory conservation of strings:
http://arduino.cc/en/Reference/PROGMEM

Arduino Serial Output Dropping Characters

I have a bizarre one here with the serial output when trying to write some code for my Arduino Uno.
I have this proto-code:
MyClass myclass;
void setup()
{
Serial.Begin(9600);
Serial.println("Starting...");
}
void loop()
{
int status = myclass.DoWork();
Serial.println("Status: " + status);
}
class MyClass
{
int DoWork()
{
Serial.println("Doing some work...");
return 1;
}
}
Now when this runs I get the following output:
Starting...
Doing some work...
atus: 1
So the strange part is the "Status: 1" missing the first few characters. Is this because I am using serial in an object improperly or something?
I have noticed when I reference another library that also uses serial like MyClass does that I get other strange output behavior... so I assume that I am doing something wrong.
EDIT: In the end this turned out to actually be a memory issue. A library I was including was quite large and it was consuming the available memory. I found this by adding a few more debugging statements and found the corruption shifted around based on the string lengths and positions. By using the F() function I moved the strings to flash memory (e.g. I now run Serial.println(F("Starting...")); and it has corrected the strange output.
You cannot add strings and integers in C++. It would have been better for you if this failed to compile:
Serial.println("Status: " + status);
Instead the compiler guessed at something. It guessed wrong. Use this:
Serial.print("Status :");
Serial.println(status);
or for complete control of outputting numbers and strings learn to use C string formatting, sprintf()
In the end this turned out to actually be a memory issue. A library I was including was quite large and it was consuming the available memory. I found this by adding a few more debugging statements and found the corruption shifted around based on the string lengths and positions. By using the F() function I moved the strings to flash memory (e.g. I now run Serial.println(F("Starting...")); and it has corrected the strange output.
One more possible explanation.
I was running minicom to monitor, and I usually like that it auto-reconnects after resetting my device.
Well I minimized a terminal running minicom last night, and today I started a new instance that somehow also got connected to the same serial port (if that is even possible).
I think the two instances of minicom were each reading ~50% of the serial characters roughly at random, leaving me with quite a mess of text.

Problems with 64 bit pointers

I am using Windows 7 and have a 64 bit and a 32 bit version of my program. The 32 bit version works perfectly fine, however, I am having issues with the 64 bit version at runtime. I have a list view item created and am filling the columns with my information. All of them are printing, but one is not printing correctly. This is what it is printing (I apologize for the lack of a picture but as a new member I am unable to post pictures):
Truck
ÍÍÍÍHRZ141
ÍÍÍÍHRZ152
It seems to be placing 4 null characters before the information I actually want it to display. Upon further examination, it appears as though the addressing is incorrect. Here is a section of my code where the error is occurring:
Audit * audit = (Audit *)plvdi->item.lParam;
switch(plvdi->item.iSubItem)
{
case 0:
{
plvdi->item.pszText = audit->Truck;
while(plvdi->item.pszText[0] != 'H')
{
plvdi->item.pszText++;
}
}
return true;
This is a temporary fix due to the fact that all of my truck names start with the character H. plvdi->item.psz text is the text display of the list view item, and audit->Truck is a char[]. It should be as simple as:
sprintf(plvdi->item.pszText, audit->Truck);
but that doesn't seem to work. It leaves me with the same error. When run, the address plvdi->item.pszText is 4 bytes less than the address of audit->Truck, after the assignment statement (breakpoint on the while statement), which I believe is causing the 4 null characters. I am just unsure as to how to resolve this problem without a work around such as the one I posted, why this is happening, and why only in the 64 bit solution. Thank you in advance for any help on this matter.
EDIT: From other similar problems I have found within my program, it seems to have something to do with pointers. Everything in my Audit class that came after a selections vector was having problems and appeared to be off by 4 bytes. In another class, I found that everything coming after a pointer to an Audit failed and I also had some issues with strings (which are technically pointers to char arrays). When I moved the elements with pointers to the end of the class in the header file, everything seemed to work fine again. Any idea if strings, vectors, or other similar structures have pointers that are dependent upon 32 or 64 bit systems?
On 64 bit windows platform, sizeof of a pointer is 8 bytes, while is 4 on a 32 bit configuration. Check your code to avoid the 4 bytes size assumption.

Unix write() function (libc)

I am making a C application in Unix that uses raw tty input.
I am calling write() to characters on the display, but I want to manipulate the cursor:
ssize_t
write(int d, const void *buf, size_t nbytes);
I've noticed that if buf has the value 8 (I mean char tmp = 8, then passing &tmp), it will move the cursor/pointer backward on the screen.
I was wondering where I could find all the codes, for example, I wish to move the cursor forward but I cannot seem to find it via Google.
Is there a page that lists all the code for the write() function please?
Thank you very much,
Jary
8 is just the ascii code for backspace. You can type man ascii and look at all the values (the man page on my Ubuntu box has friendlier names for the values). If you want to do more complicated things you may want to look at a library like ncurses.
You have just discovered that character code 8 is backspace (control-H).
You would probably be best off using the curses library to manage the screen. However, you can find out what control sequences curses knows about by using infocmp to decompile the terminfo entry for your terminal. The format isn't particularly easy to understand, but it is relatively comprehensive. The alternative is to find a manual for the terminal, which tends to be rather hard.
For instance, I'm using a color Xterm window; infocmp says:
# Reconstructed via infocmp from file: /usr/share/terminfo/78/xterm-color
xterm-color|nxterm|generic color xterm,
am, km, mir, msgr, xenl,
colors#8, cols#80, it#8, lines#24, ncv#, pairs#64,
acsc=``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,
bel=^G, bold=\E[1m, clear=\E[H\E[2J, cr=^M,
csr=\E[%i%p1%d;%p2%dr, cub=\E[%p1%dD, cub1=^H,
cud=\E[%p1%dB, cud1=^J, cuf=\E[%p1%dC, cuf1=\E[C,
cup=\E[%i%p1%d;%p2%dH, cuu=\E[%p1%dA, cuu1=\E[A,
dch=\E[%p1%dP, dch1=\E[P, dl=\E[%p1%dM, dl1=\E[M, ed=\E[J,
el=\E[K, enacs=\E)0, home=\E[H, ht=^I, hts=\EH, il=\E[%p1%dL,
il1=\E[L, ind=^J,
is2=\E[m\E[?7h\E[4l\E>\E7\E[r\E[?1;3;4;6l\E8, kbs=^H,
kcub1=\EOD, kcud1=\EOB, kcuf1=\EOC, kcuu1=\EOA,
kdch1=\E[3~, kf1=\E[11~, kf10=\E[21~, kf11=\E[23~,
kf12=\E[24~, kf13=\E[25~, kf14=\E[26~, kf15=\E[28~,
kf16=\E[29~, kf17=\E[31~, kf18=\E[32~, kf19=\E[33~,
kf2=\E[12~, kf20=\E[34~, kf3=\E[13~, kf4=\E[14~,
kf5=\E[15~, kf6=\E[17~, kf7=\E[18~, kf8=\E[19~, kf9=\E[20~,
kfnd=\E[1~, kich1=\E[2~, kmous=\E[M, knp=\E[6~, kpp=\E[5~,
kslt=\E[4~, meml=\El, memu=\Em, op=\E[m, rc=\E8, rev=\E[7m,
ri=\EM, rmacs=^O, rmcup=\E[2J\E[?47l\E8, rmir=\E[4l,
rmkx=\E[?1l\E>, rmso=\E[m, rmul=\E[m,
rs2=\E[m\E[?7h\E[4l\E>\E7\E[r\E[?1;3;4;6l\E8, sc=\E7,
setab=\E[4%p1%dm, setaf=\E[3%p1%dm, sgr0=\E[m, smacs=^N,
smcup=\E7\E[?47h, smir=\E[4h, smkx=\E[?1h\E=, smso=\E[7m,
smul=\E[4m, tbc=\E[3g, u6=\E[%i%d;%dR, u7=\E[6n,
u8=\E[?1;2c, u9=\E[c,
That contains information about box drawing characters, code sequences generated by function keys, various cursor movement sequences, and so on.
You can find out more about X/Open Curses (v4.2) in HTML. However, that is officially obsolete, superseded by X/Open Curses v7, which you can download for free in PDF.
If you're using write just so you have low-level cursor control, I think you are using the wrong tool for the job. There are command codes for many types of terminal. VT100 codes, for example, are sequences of the form "\x1b[...", but rather than sending raw codes, you'd be much better off using a library like ncurses.

Resources