Project - Arduino based DaisyLink module

lol…

one issue I ran into and i’m not sure why…
if I use this code in a while loop, the mainboard looses the connection to the module and throws an exception:


         bool jay = true;
            while (true)
            {
jay = !jay;
Thread.Sleep(100); //if I remove the sleep it stops instantly.. if I increase the time it runs longer but eventually looses the connection...
   genericDaisylink.WriteRegister(0x1, (byte)(jay ? 1 : 0));
}


any ideas ???

Cheers,
Jay…

I have to check. I have stopped messing with that code as soon as I got it working.
It is possible that there is a bug on the arduino side.

I am finishing something that I am very excited about and then I will take a look at the ArduinoDL unless you’ll figure it out by then.

alright spit it out man what is it?

I will share as soon as I can.

3 Likes

here is the setup of the upstream port only which is working but not stable if the loop is tight and both are running off of the same Computer (power source)…

so if I move the Arduino to a battery power, things get better but I can only get the loop to run with a minimum of Thread.sleep(50); anything below that will cause the line to get lost… my guess is NOISE on the lines…

we’ll keep digging…

Cheers,
Jay.

Hello again.
Do you know how would I send data from the Arduino to the Mainboard?

I can’t seem to find the how to?
another i’m confused about…

also, say I want to send a string from Mainboard to slave and back …
would I have to create my own start register and stop register and connate the bytes to complete the transmission ?
is that how it should be done?

cheers,
Jay.

@ Jay Jay - The daisy link protocol does not cater to sending data to the mainboard. From the mainboard you either read from or write to registers on the DL device, but what is not immediately obvious is that the registers are not limited to one byte. if you take a look at the DL40IO firmware, you will see that I have multi byte registers, so you could have a register that you write your string to and another register that you read the response from.

In cases that you want the DL device to “send” data to the mainboard, you can put the data in a register and raise an interrupt which triggers the mainboard to read the data register. If you need more control you can have a status register that the mainboard will read when it receives the interrupt, the status register will indicate what it was that caused the interrupt and therefore what the mainboard needs to go read etc.

1 Like

Hello again,
Thank you guys for all your help…

ok I have both upstream and down stream working arduino >> MutiLED >> MultiLED all working :)…

I did manage to send large string to Arduino but I used my own start and stop indicators…
as for the DL40 I tried to review the firmware and I did notice the following code:


    private ushort ReadUInt16(byte register)
    {
      int bytesWritten;
      int bytesRead;

      _oneByte[0] = register;
      this.WriteRead(_oneByte, 0, 1, _eightBytes, 0, 2, out bytesWritten, out bytesRead);
      return (ushort)(_eightBytes[0] | (_eightBytes[1] << 8));
    }

is this the right code i’m looking for? of course I still have to find it’s match on the firmware…

i’ll keep digging :slight_smile:

oh btw I used the Extender Module to connect the Upstream and downstream with a simple modification of course thanks to IAN’s Blog for that :slight_smile:

thanks.
Jay.

That is the correct code, you will see ReadUInt32/64 etc. as well, each of these are reading multiple bytes from a single register. On the firmware side, DL40.c contains a function called DL_Platform_ReadRegister, this function takes the register and the offset into the register as arguments, for a multi-byte read the function is called with the same register but with an increasing offset. The Arduino firmware would need similar support for reading registers.

So you could for example encode the string as a length prefixed string, the the first byte might be the length and the subsequent bytes the characters in the string. Of course if you need more than 255 characters you could use a multi-byte prefix.

hello again:

i’m not able to raise an interrupt… can someone please help me out:

I noticed this code in your GadgeteerDaisylink.cpp Architect:


void GadgeteerDaisyLink::notifyMainBoard()
{		
}

is this the missing piece to notify the mainboard to read a register?

thanks.

Looks like it.

Just follow the spec. You need to set something in one of the registers and then pull the uplink high or low.

@ Jay Jay - By the way the project is on GitHub. If you fix something and would like to share back feel free to “fork&pull” or I can give you push access.

I will if I ever succeed :slight_smile: thanks for sharing.

so this is what the guide says:

so according to the above I’ll have to pull INT0 aka Pin3(Extender) LOW for a max of 1ms…

what does it mean for a max of 1 ms?
will something like this work:


void GadgeteerDaisyLink::notifyMainBoard()
{	
	pinMode(2, OUTPUT);
	digitalWrite(2, LOW);
}

I just picked up Arduino with this project so i’m reading as much as I can, but I’m impatient to get it working :slight_smile:

Cheers,
Jay.

That means you have to release it after waiting for 1ms. But before that you have to change the bit in the config register, so the mainboard can read it and distinguish your module as the source of the interrupt.



Most likely you will need to do more than that, unless there is only one type of interrupt in your module.

Raising interrupts on the module side is quite intricate, you need to take the neighboring bus state into account. It might help to use the DL40IO implementation as a reference.

Take a look at DL_Interrupt() in DaisyLink.c. this function initiates the interrupt and records sets a flag indicating that we are controlling the bus. In the same file the DL_Process() function is responsible for resetting the state and the bus if this module is driving the bus, see the STATE_ACTIVE case in the code, the main procedure calls DL_Process() in a loop, so this function is being called continuously.

I have not looked at the Arduino implementation, so I do not know how well this matches the implementation, there are many ways to achieve this. I hope it can at least give you an idea of how the protocol specification regarding interrupts can be translated to code.

1 Like

Thank you guys,
I got it to work…
there is a bug in Architect’s code that was driving me nuts…

thanks taylorza for the DL40IO as it helped me understand a bit on how things work which helped find the bug…

at least the interrupt event is raised in C#… now onto the next step…

cheers,
Jay.

@ Jay Jay - what was the bug about?

it’s here:


		if( digitalRead(2) == LOW  && daisy_state !=1 )//Reset State
		{
....................
 }

which traps the code when the pin is low and state is 2, also you are not setting state to active=3 … so changing the code to :


		if( digitalRead(2) == LOW  && daisy_state == 0 )//Reset State
		{
..............
                }

fixed the problem…

and here is the updated notifyMainBoard()


void GadgeteerDaisyLink::notifyMainBoard()
{	
	daisy_Registers[REGISTER_DAISY_CONFIG] |= 0x80;
	pinMode(2, OUTPUT);
	digitalWrite(2, LOW);
}

I still need to implement the code to clear the interrupt which must be handled when State is active=3…

cheers,
Jay.

2 Likes

@ Jay Jay - Good one. I think mainboard supposed to clear the flag once it determines which mode raised it.

I think we still have to clear the flag in our code after the mainboards notify us…
As of now the flag is not being cleared .

I think the library is missing the proper code… we’ll keep digging…

Cheers