NXC: program blocks caused by PlayTones()

Discussion specific to NXT-G, NXC, NBC, RobotC, Lejos, and more.
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

NXC: program blocks caused by PlayTones()

Post by HaWe »

I added some PlayTones() to my program for status signalizing and debugging.

Now after playing the sound melody the program flow always blocks (freezes), the NXT makes a frequently cheeping noise (> 10kHz) or the motor mux crackles -
and nothing happens to the program any more.

Code: Select all

Tone sndChordUp[]   = {TONE_C4,50, TONE_E4,50, TONE_G4,50,
                        TONE_C5,50, TONE_E5,50, TONE_G5,50, TONE_C6,200};
...
  PlayTones(sndChordUp); 
Anyway, it still is reacting to a touch pressure polled by an Emergency Stop tasks.

This malfunction is new since I'm using a touch muxer (homebrewed PCF8574) and a motor muxer (MS_MTRMX) instead of a 2nd NXT (formerly paired shakily by BT)
- I'm not sure if an interference with a muxer is the reason why.

if I remove the Playtones() command then the program runs fine.

here's a snippet:

Code: Select all


/******************************************************************************/
task main(){
/******************************************************************************/
  char EP,                            // flag: en passant
       RK,                            // flag: castling=Rochade
       CK, CM,                        // flag: check!=Schach! (1&8, 1&16)
       turn,                          // side on turn
       chosen;                        // manual or auto move from stdin input;
  char board[129];                    // Piece K_start-> L_dest
  int K, L,                           // score local, remote
      score, rscore1, rscore2, rscore3, idum, buf;
  char PMOD=0, m1, m2, m3;
  string s;


// init all defauts
  Init();
  InitIOports();
  InitLookupTable();

  start EmergencyStop;
  start GetPCF8574Values;
  start PneumPressurePump;
  start DisplayValues;

// chess robot setup

  Claw_close(); Wait(500);
  Claw_open();  Wait(500);
  Hand_up();    while (!SensorT_Cup);
  

  RobotArmsZeroInit();
  PlayTones(sndChordUp);            // <<<< blocks if not outcommented
  
  
  // align board center base line
  Claw_close(); Wait(500);

  
  statusline="=> sqr. 128  ";
  MoveClawTo(128);
  
  PlayTones(sndChordUp);           // <<<< blocks if not outcommented
  
  Coast(OUT_ABC); Wait(200);

  // single chess square alignment
  Hand_up();  while (!SensorT_Cup);  Claw_open();

  stop DisplayValues; statusline=clrln;
  buf=Menu("Calibrate ?", "/9  /ALL  /no");
the whole NXC code:
chess 459singleNXT.zip
main program, motor and sensor control
(6.86 KiB) Downloaded 290 times
CHESS_AI_ENGINE_H.zip
chess engine & toolbox
(11.48 KiB) Downloaded 296 times

any ideas?
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC: program blocks caused by PlayTones()

Post by HaWe »

has no one an idea why Playtones() can block up a program?
afanofosc
Site Admin
Posts: 1256
Joined: 26 Sep 2010, 19:36
Location: Nashville, TN
Contact:

Re: NXC: program blocks caused by PlayTones()

Post by afanofosc »

I'm inclined to think it is because this function is getting called on two separate threads simultaneously. I didn't analyze the full program to say whether it is doing that or not. But it is not inline or safecall so if you do call it in a subroutine (inline or not) that gets called from a thread other than main you could get a lockup due to the fact that non-inline and non-safecall functions are not thread safe and care must be taken that they are not called at the same time from two different threads.

You could declare a mutex globally called "mutexSoundSystem" and acquire it before calling PlayTones and release it after calling PlayTones everwhere that you call PlayTones and see if that makes the problem go away.

John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC: program blocks caused by PlayTones()

Post by HaWe »

John, thank you for your hint.
I added

Code: Select all

 mutex tmutex;

safecall void PlayTonesSCall(Tone snd[]) {
  Acquire(tmutex);
  PlayTones (snd);
  Release(tmutex);
}
I replaced all PlayTones in every function or task by PlayTonesSCall - but it all is still the same malfunction: the robot plays the sound but then immediately hangs up.
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC: program blocks caused by PlayTones()

Post by HaWe »

no ideas any more...?
afanofosc
Site Admin
Posts: 1256
Joined: 26 Sep 2010, 19:36
Location: Nashville, TN
Contact:

Re: NXC: program blocks caused by PlayTones()

Post by afanofosc »

I would try to create a simple test program that locks up when you use PlayTones. You can try replacing PlayTones with its equivalent. It just iterates through an array of Tone structures and calls PlayTone for each one.

John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC: program blocks caused by PlayTones()

Post by HaWe »

edit: aahm - no - I don't actually get what you mean
simple programs did never block, even before it didn't ever block, but now my big one including the 2 muxers blocked unforeseen.

But I replaced all

Code: Select all

safecall void PlayTonesSCall(Tone snd[]) {
  Acquire(tmutex);
  PlayTones (snd);
  Release(tmutex);
}
by

Code: Select all

safecall void beep(int frq, int dur) {
   PlayTone(frq, dur); Wait(dur);
}
and now it works fine again.

surprise, surprise... :o
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC: program blocks caused by PlayTones()

Post by HaWe »

...
@John:
no idea why PlayTones() blocks while PlayTone() doesn't?
(actually there is no PlayTone(s) contemporaneously in different tasks)
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC: program blocks caused by PlayTones()

Post by HaWe »

could it be that the PlayTones-running task blocks because PlayTones doesn't use proportionate long wait states internally after playing each single tone?
Maybe thus the scheduler conflicts with other running tasks?
afanofosc
Site Admin
Posts: 1256
Joined: 26 Sep 2010, 19:36
Location: Nashville, TN
Contact:

Re: NXC: program blocks caused by PlayTones()

Post by afanofosc »

Here is the definition of PlayTones from the NXCDefs.h header file.

Code: Select all

void PlayTones(Tone tones[])
{
  for (int i = 0; i <  asm { arrsize __RETVAL__, tones }; i++) {
    Tone tmp = tones[i];
    PlayTone(tmp.Frequency, tmp.Duration);
    asm { waitv tmp.Duration };
  }
}
Feel free to fiddle with this to see where it might be going wrong. Certainly you can't call this non-inline, non-safecall function from more than one thread simultaneously.

John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
Post Reply

Who is online

Users browsing this forum: No registered users and 5 guests