tom-2015 / rpi-ws2812-server

Raspberry Pi WS2812 (web) server tool
172 stars 39 forks source link

It doesn't work with the -p flag #32

Open leoheck opened 4 years ago

leoheck commented 4 years ago

Hi, I could not make it run with the -p flag. I am using RPi3 and RPi4.

Do you have any (bash) example to share here?

I am trying something like:

sudo ./ws2812svr -p /dev/leds &
sudo echo "setup 1,8,1; init; fill 1,ff00000; render" > /dev/leds
sudo ./ws2812svr -p /dev/leds &
sudo echo "setup 1,8,1" > /dev/leds
sudo echo "init" > /dev/leds
sudo echo "fill 1,ff00000" > /dev/leds
sudo echo "render" > /dev/leds

Is it right? Am I doing anything wrong?

leoheck commented 4 years ago

I am seeing the main.c and I found this:

printf ("Opening %s as named pipe.", named_pipe_file);

The file is being created but the printf is not being executed. So maybe the code needs some work to solve it

leoheck commented 4 years ago

Actually the error is here:

input_file = fopen(named_pipe_file, "r");
leoheck commented 4 years ago

I made it work by recreating the FIFO every time. I don't know if it is right thing to do, but it worked by now.

    while (exit_program==0) {
        if (mode==MODE_TCP){
            c = 0;
            if (read(active_socket, (void *) & c, 1)<=0) c = EOF; //returns 0 if connection is closed, -1 if no more data available and >0 if data read
        }else{
            c = fgetc (input_file); //doesn't work with tcp
        }

      if (c!=EOF){
        process_character(c);
      }else{
        //end of file or read error
        switch (mode){
            case MODE_TCP:
                if (!exit_program){
                    tcp_wait_connection(); //go back to wait for connection
                }
                break;
            case MODE_NAMED_PIPE:
                // usleep(10000);

                remove(DEFAULT_DEVICE_FILE);
                mkfifo(DEFAULT_DEVICE_FILE, 0777);
                chmod(DEFAULT_DEVICE_FILE, 0777);
                input_file = fopen(DEFAULT_DEVICE_FILE, "r");

                break;
            case MODE_STDIN:
                usleep(10000);
                break;
            case MODE_FILE:
                process_character('\n'); //end last line
                if (ftell(input_file)==feof(input_file))  exit_program=1; //exit the program if we reached the end
                break;
        }
      }
    }
tom-2015 commented 4 years ago

Seems to work fine here maybe try added a ; after render? sudo echo "setup 1,8,1; init; fill 1,ff00000; render" > /dev/leds Tested with Raspbian stretch but will try later in buster maybe that is the problem?

leoheck commented 4 years ago

Oh, sure, maybe that is the problem.

Look, this is my system. image

I just replaced this

case MODE_NAMED_PIPE:
    remove(DEFAULT_DEVICE_FILE);
    mkfifo(DEFAULT_DEVICE_FILE, 0777);
    chmod(DEFAULT_DEVICE_FILE, 0777);
    input_file = fopen(DEFAULT_DEVICE_FILE, "r");
    break;

By this, because it was giving me segfault.

case MODE_NAMED_PIPE:
    fclose(input_file);
    input_file = fopen(DEFAULT_DEVICE_FILE, "r");
    break;

If you find something, please let me know. And thank you for this project, it is awesome.

tom-2015 commented 4 years ago

You're right the file needs to be reopened. I will fix this as soon as possible and add some other things too.

leoheck commented 4 years ago

Cool! It will be nice.

tom-2015 commented 4 years ago

should not be fixed added one extra command and will try to add more things later

leoheck commented 4 years ago

You can also add some examples in the README.md to make clear for other folks how to use this feature.

leoheck commented 4 years ago

Since you are working hard, I have one question.

Is it possible to create a command to stop/halt the current execution?

I am sending a lot of commands (the whole animation) for the FIFO device with an external loop in bash (for example). Then, I want to stop the current animation to send another animation. But looks like the server keeps playing the previous animations for a while.

tom-2015 commented 4 years ago

Yes it will read until everything is processed and it reads line by line from FIFO and executes it so this makes it difficult to add a stop command at this moment because when it will read this command it's already too late...

One thing you could to is restart it (sudo killall ws2812svr and sudo ./ws2812svr -p) or use a TCP connection and thread command. With TCP you can first store all commands in memory and then start a thread executing them. Next time you connect to the TCP port it will automatically stop the current animation and do anything new.

leoheck commented 4 years ago

I am doing the same as you said.

But I am thinking further. Do you think it is too much to create a second FIFO to make this kind of action possible? For example, if you right stop/halt to this second FIFO, it should stop the execution immediately. Alternative commands are also possible I think, like pause until a start commando is sent or even pause for some time.

leoheck commented 4 years ago

You said

should not be fixed

Maybe it is almost working, I just found that it is not working fine. https://github.com/tom-2015/rpi-ws2812-server/issues/34