i am using an ATtiny to receive serial commands and respond to them by transmitting infrared commands.
what i would like to do is simulate the original remote, and one of the features of the remote is to have extra commands if the button is held down.
i made a mock up with a regular arduino and loading up hyper terminal on the computer. when i hold down a key on the computer it triggers the arduino and the device responds as if a remote with the button held down has been pointed at it. in other words it works fine
but then i ported the code to an ATtiny85 using an external 16mhz resonator (the same as the ones on the arduino pro mini) and of course i had to use Softserial but now the hold feature doesn't work
sending one serial command works perfectly, but sending serial commands repeatedly doesn't work like it did on the regular arduino
i hope all that makes sense, its a bit difficult to explain but one thing i would like to know is the possible limits of softserial compared to hardware serial
why do people on this forum have to be so passive aggressive?
Who's being passive?
while (mySerial.available() > 1) { //removes lag, serial fills up and continues to repeat scommands even after serial input has stopped
mySerial.read();
}
Why? If there is more than one byte in the buffer, throw away all the data except the last byte. Perhaps the data that you want just hit the bit bucket.
case 99: //c
Wouldn't
case 'c':
be easier to understand and modify (and maintain)?
what are the limits of software serial compared to hardware serial?
Software serial's interrupts can interfere with other things on the Arduino (or ATTiny). HardwareSerial's interrupts are processed much faster, so the possibility of interference is less.
the while loop removes excess data so that only current data is being processed, if no more data is received then i don't want it to continue processing data in the buffer. but i have tried the code without this loop and still doesn't work, and this loop does work on the ATmega328 version, so i know the loop is not to blame.
thanks for the recommendation i will change my case statements to ASCII
can you be a bit more specific about what conflicts with software serial? as i said before, the atmega version works fine with hardware serial so i am assuming that the problem lies with the software serial.
It has software serial routines which are designed to mimic the way the hardware serial library does, which means you dont need the softwareserial library, simply use the normal Serial.print(), Serial.available(), Serial.read() commands etc. as you would for a regular arduino. There are no set baud rates, and I have had success with rates as high as 115200.
There are two small caveats/differences between it and Hardware serial.
The first is that TX must be digital 0 and RX must be digital 1 (which is just swapping RX and TX in your case). This i because my library uses the built in analog comparator to supply an interrupt vector. It features the same ring buffer as Hardware Serial does meaning that polling is not required.
The second is that is cannot transmit and recieve Serial data at the same time (its Half Duplex), but you don't appear to need to.
I tried the new core but unfortunately the results were still the same, it seems like what ever difference there is between hardware and software serial, is the difference between this working and not working.
the only thing i can think is happening is that the ATtiny is picking up a serial byte right in the middle, this would then be rejected by the switch case as not a valid input and for a fraction of a second the ATtiny would stop transmitting IR, and the receiver might interpret that as a button debounce on the remote control.
it works fine if i have separate commands that drive the hold functions, and basically loop round and retransmit the IR signal about 16 times, but thats not really what i was hoping for. my original idea was going to use an ATmega382 but it seemed like such a waste for such a simple job, but the lack of hardware serial on the ATtiny85 makes it very difficult to do what i want to do.
To prove it's a software serial problem and not an ATtiny one could you try it on your 328 using software serial instead of hardware serial. Maybe jumper the hardware RX/TX pins to a couple of normal pins that software serial reads/writes. Maybe it's something simple like you need to pull down the RX pin on your hardware.
the serial is being sent from a computer, at the moment it is from Hyper terminal but in the future it will be a custom application.
also in the final version this will be driven with RS232, where as at the moment i am using the FTDI chip from the arduino board.
i am not sure how i would try software serial on a 328? the board has the FTDI chip hard wired to TX and RX, at the moment i am using the board with the chip removed just as a serial converter to drive the ATtiny. if i use the original 328, won't the hard wired tx and rx pins automatically interrupt the processor even if i jump those pins over to a software serial port?
i am sure the ATtiny is using the external resonator because it doesn't respond if i disconnect it, but it may be that the resonator is not accurate enough, maybe it needs a real crystal...
thanks for the replies everyone
just as a note, i think i have worked out a fix to solve my problem. instead of asking the ATtiny to transmit on receiving serial and expect it to transmit at regular enough intervals, i am going to get it to transmit on receiving a single serial command and repeat that command until it receives a stop command. it might not work because if the ATtiny misses that stop command it could be transmitting for ever. i can put a limit in to maybe stop after 16 transmissions, but still it may not work
i am not sure how i would try software serial on a 328? the board has the FTDI chip hard wired to TX and RX, at the moment i am using the board with the chip removed just as a serial converter to drive the ATtiny. if i use the original 328, won't the hard wired tx and rx pins automatically interrupt the processor even if i jump those pins over to a software serial port?
I did not realize you was using the arduino board. That seems to rule out hardware problem unless the patch cables to the ATtiny are long/noisy.
I'm not sure about the core of arduino but I would expect the hardware UART pins only gets configured and used if you do a Serial.begin otherwise the pins should behave just like any other pins.
hmmm, if the patch cables to the ATtiny where to long, (including the one to the resonator) could that have an effect?
at the moment i have ribbon cable soldered directly to an SMD 85, the ribbon cable is maybe 8cm long. at the other end they are attached to the arduino board, and two of the wires are stripped back and attached to the SMD resonator.
could it be that the resonator is too far from the chip? it has internal capacitors btw
NeX:
hmmm, if the patch cables to the ATtiny where to long, (including the one to the resonator) could that have an effect?
at the moment i have ribbon cable soldered directly to an SMD 85, the ribbon cable is maybe 8cm long. at the other end they are attached to the arduino board, and two of the wires are stripped back and attached to the SMD resonator.
A long lead like this will effect the resonator signal but not sure if this would be the cause. Can you program the ATtiny to use the internal 8Mhz clock instead if the Serial rate is not to high.
it was my understanding that the internal resonator is too unpredictable to function with serial, but i have moved the crystal so it is now within a few millimeters of the ATtiny and there is no change.
i have however found a possible work around, but it is not responding perfectly.
can someone take a look at this code and maybe see if there is a better way of doing it? the code also doesn't allow for different serial commands, only to exit the existing one, which is no good.
case 's':
while (!stopByte) {
um_sendNEC(0xB54A58A7, 32); //SRC
IRcount ++;
if (Serial.available() > 0) {
if (Serial.read() == 'x') stopByte = true;
}
if (IRcount >= 16) stopByte = true;
}
IRcount = 0;
stopByte = false;
break;