0
Offline
Jr. Member
Karma: 0
Posts: 59
Arduino rocks
|
 |
« on: January 07, 2013, 02:54:21 pm » |
hi all,
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
thanks guys!
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Online
Brattain Member
Karma: 313
Posts: 35487
Seattle, WA USA
|
 |
« Reply #1 on: January 07, 2013, 02:57:02 pm » |
"Hi guys. I have a code problem, but I'm not going to show you any code. Please help".
Did I paraphrase that correctly?
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Jr. Member
Karma: 0
Posts: 59
Arduino rocks
|
 |
« Reply #2 on: January 07, 2013, 03:08:47 pm » |
why do people on this forum have to be so passive aggressive? no matter how much code i post it wont answer my question: "what are the limits of software serial compared to hardware serial?" but seeing as people don't read unless it is in a little code window, here: #include <SoftwareSerial.h>
SoftwareSerial mySerial(0, 1); // RX, TX
#define TOPBIT 0x80000000
#define NEC_HDR_MARK 9000 #define NEC_HDR_SPACE 4500 #define NEC_BIT_MARK 560 #define NEC_ONE_SPACE 1600 #define NEC_ZERO_SPACE 560 #define NEC_RPT_SPACE 2250
int inByte = 0;
void setup() { DDRB = DDRB &~B00000100; PORTB = PORTB &~B00000100; mySerial.begin(9600); }
void loop() { while (mySerial.available() > 1) { //removes lag, serial fills up and continues to repeat scommands even after serial input has stopped mySerial.read(); } if (mySerial.available() > 0) { inByte = mySerial.read(); switch (inByte) { case 99: //c um_sendNEC(0xB54A9867, 32); //Wheel Clockwise um_sendNEC(0xF50AFE01, 32); //Wheel Clockwise break; case 97: //a um_sendNEC(0xB54A9867, 32); //Wheel Anticlockwise um_sendNEC(0xF50A7E81, 32); //Wheel Anticlockwise break; case 98: //b um_sendNEC(0xB54A9867, 32); //Centre Button um_sendNEC(0xF50ABE41, 32); //Centre Button break; case 43: //+ um_sendNEC(0xB54A50AF, 32); //Vol Up break; case 45: //- um_sendNEC(0xB54AD02F, 32); //Vol Down break; case 114: //r um_sendNEC(0xB54A48B7, 32); //BAND break; case 116: //t um_sendNEC(0xB54A30CF, 32); //ATT break; case 100: //d um_sendNEC(0xB54A9867, 32); //DISP um_sendNEC(0xF50AB649, 32); //DISP break; case 115: //s um_sendNEC(0xB54A58A7, 32); //SRC break; case 101: //e um_sendNEC(0xB54AD22D, 32); //EQ break; case 102: //f um_sendNEC(0xB54A9867, 32); //DF um_sendNEC(0xF50A16E9, 32); //DF break; case 117: //u um_sendNEC(0xB54A02FD, 32); //Up break; case 111: //o um_sendNEC(0xB54A827D, 32); //Down break; case 108: //l um_sendNEC(0xB54A42BD, 32); //Left break; case 105: //i um_sendNEC(0xB54AC23D, 32); //Right break; default: inByte = 0; } // mySerial.write(inByte); inByte = 0; } }
void um_sendNEC(unsigned long data, int nbits) { um_mark(NEC_HDR_MARK); um_space(NEC_HDR_SPACE); for (int i = 0; i < nbits; i++) { if (data & TOPBIT) { um_mark(NEC_BIT_MARK); um_space(NEC_ONE_SPACE); } else { um_mark(NEC_BIT_MARK); um_space(NEC_ZERO_SPACE); } data <<= 1; } um_mark(NEC_BIT_MARK); um_space(0); }
void um_mark(int time) { DDRB = DDRB | B00000100; delayMicroseconds(time); }
void um_space(int time) { DDRB = DDRB &~B00000100; delayMicroseconds(time); }
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Online
Brattain Member
Karma: 313
Posts: 35487
Seattle, WA USA
|
 |
« Reply #3 on: January 07, 2013, 03:23:36 pm » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Jr. Member
Karma: 0
Posts: 59
Arduino rocks
|
 |
« Reply #4 on: January 07, 2013, 04:25:56 pm » |
thank you for the reply,
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.
|
|
|
|
|
Logged
|
|
|
|
|
Leeds, UK
Offline
God Member
Karma: 35
Posts: 983
Once the magic blue smoke is released, it won't go back in!
|
 |
« Reply #5 on: January 07, 2013, 05:02:24 pm » |
Can I suggest you try the tiny core I wrote? https://github.com/TCWORLD/ATTinyCoreIt 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.
|
|
|
|
|
Logged
|
~Tom~
|
|
|
|
0
Offline
Jr. Member
Karma: 0
Posts: 59
Arduino rocks
|
 |
« Reply #6 on: January 08, 2013, 04:22:33 am » |
thanks very much for that Tom,
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.
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
Dallas
Offline
Shannon Member
Karma: 118
Posts: 10153
|
 |
« Reply #7 on: January 08, 2013, 04:31:50 am » |
i am using an ATtiny to receive serial commands... Sent from what?
|
|
|
|
|
Logged
|
|
|
|
|
Norfolk UK
Offline
Edison Member
Karma: 23
Posts: 1320
|
 |
« Reply #8 on: January 08, 2013, 04:33:18 am » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
Dallas
Offline
Shannon Member
Karma: 118
Posts: 10153
|
 |
« Reply #9 on: January 08, 2013, 04:35:02 am » |
but then i ported the code to an ATtiny85 using an external 16 MHz resonator... Are you certain the processor is running from the resonator and not the internal oscillator?
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Jr. Member
Karma: 0
Posts: 59
Arduino rocks
|
 |
« Reply #10 on: January 08, 2013, 04:41:39 am » |
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
|
|
|
|
|
Logged
|
|
|
|
|
Norfolk UK
Offline
Edison Member
Karma: 23
Posts: 1320
|
 |
« Reply #11 on: January 08, 2013, 04:53:08 am » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Jr. Member
Karma: 0
Posts: 59
Arduino rocks
|
 |
« Reply #12 on: January 08, 2013, 04:56:52 am » |
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
|
|
|
|
|
Logged
|
|
|
|
|
Norfolk UK
Offline
Edison Member
Karma: 23
Posts: 1320
|
 |
« Reply #13 on: January 08, 2013, 06:38:39 am » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Jr. Member
Karma: 0
Posts: 59
Arduino rocks
|
 |
« Reply #14 on: January 08, 2013, 06:41:50 am » |
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;
|
|
|
|
|
Logged
|
|
|
|
|
|