What's the problem in given code? Why it is not showing the output for rs232 when we connect it by the d-9 connector with the short of pin number 2 & 3 in that?
#include <bios.h>
#include <conio.h>
#define COM1 0
#define DATA_READY 0x100
#define SETTINGS ( 0x80 | 0x02 | 0x00 | 0x00)
int main(void)
{
int in, out, status;
bioscom(0, SETTINGS, COM1); /*initialize the port*/
cprintf("Data sent to you: ");
while (1)
{
status = bioscom(3, 0, COM1); /*wait until get a data*/
if (status & DATA_READY)
if ((out = bioscom(2, 0, COM1) & 0x7F) != 0) /*input a data*/
putch(out);
if (kbhit())
{
if ((in = getch()) == 27) /* ASCII of Esc*/
break;
bioscom(1, in, COM1); /*output a data*/
}
}
return 0;
}
Well, the code looks alright. Have you really connected the remaining pins correctly in the plug, see serial and pin connections.
Nothing obvious stands out from your code as the cause. Check all your bases as you are dealing with hardware/software. The following Microsoft article has a different implementation using _bios_serialcom (from bios.h) which might be a good reference point for you.
http://support.microsoft.com/kb/39501
Suggestions for where to go from here:
I would also suggest replacing the literals (eg 0x08) using the constants predefined for Baud rate, Parity (eg _COM_NOPARITY) to make the code more readable in your question.
Check that the Com port is actually open, as its a assumption which is unchecked in your code example above.
Also check up on the pin connections for the DB9. To connect two computers/devices you will need to null modem it, eg pin 2 to pin 3 at the other end, plus the Signal Ground. Make sure you are disabling/not looking for DTR.
If the other computer/device is setup then I would suggest first running HyperTerminal (Programs->Accessories->Communication) and connect to your COM 1 and check you can see characters from the other device. If not its most likely related to your cable.
Hope that helps.
Before checking with your code always check your serial communication with a terminal program. I don't have much experience with Windows environment but in Linux you have programs like cutecom or gtkterm where you can send/receive data from serial port. We extensively used these programs for serial communication in Linux, they are great for debugging potential problems with serial port interface (both h/w & s/w as well). So, before suspecting your code check with a terminal emulator program.
Hey, I am not an expert on Win32, but it seems to be easier to use another article as a source (the one mentioned here before looks outdated):
http://msdn.microsoft.com/en-us/library/ms810467
This is old too, dated around 1995, but it looks still effective. The NT architecture is very restrictive when it comes to grant access to hardware, for example, to send bytes to a PC paralell port one needs to rely on workarounds dll written by open source developers.
I'm assuming from your comment about "pin 2 & 3" that you've connected a loopback cable, so you're expecting to see anything you type come up on the screen (and stop doing so when you disconnect the cable).
I think there's a bug in the code: the if (kbhit()) is inside the if (status & DATA_READY).
That means you only check the keyboard if there is some input ready to receive from the serial port - which there won't be, because you haven't sent it anything yet! Try moving the test and see if it improves matters.
(Here is some similar serial port code that puts the if (kbhit()) test outside the DATA_READY check. It doesn't claim to work, but provides some evidence that this might be the source of the problem...)
Related
My end goal is to try and send some simple data that's stored on my Raspberry pi 3 to an external server/website using a sim800c from a c++ program. I believe the easiest way to do this is to issue "AT commands" to the sim/modem however I'm struggling to do this. I can't figure out how I'm actually suppose to issue AT commands or how I can check if they're working. For testing purposes I've written some code which should send a text message to a phone number once I've gotten this working it should be fairly straight forward to figure out the AT commands to communicate with a server.
Below is an image of how I've wired everything up which I'm fairly confident is correct.
https://i.imgur.com/zysmNXE.jpg
Below is the basic c++ code that I've written using various guides, it compiles and runs in terminal however I don't get any response from the AT commands and more importantly as far as I can tell their not actually being executed. I've tried changing the fake number to my personal one but it didn't make a difference.
#include <stdio.h>
#include <string.h>
#include <wiringPi.h>
#include <wiringSerial.h>
int main ()
{
int connection;
printf("Opening connection \n");
connection = serialOpen("/dev/ttyAMA0", 9600);
delay(1000);
printf("Connection: %d\n", connection);
printf("\n");
//Set gsm to text mode
serialPuts(connection,"AT+CMGF \r\n");
delay(1000);
//Number that the message should be sent to
serialPuts(connection,"AT+CMGS=\"12345678900\"\r\n");
delay(1000);
//The message
serialPuts(connection,"Hello World");
delay(1000);
//Print ctrl+x
serialPuts(connection,"\x1A");
delay(1000);
printf("Done \n");
return 0 ;
}
As far as I can tell there are 3 likely reasons why it's not working;
A possible config/settings issue with the pi
I've wired it up incorrectly
The sim/module isn't working
I'm just not sure how to go about testing/finding what is causing the issue. If I could get my code to output the response of the AT commands after doing "serialPuts" that might help me figure out whats going on but I haven't made much luck doing that. Alternatively If anyone has an idea why the commands don't appear to be working or can provide me some ways to debug/test them that would be great.
The issue turned out just to be a simple wiring mistake.
I had wired the txd pin of the sim module to the txd pin on the raspberry pie as I was under the impression you just needed to match the pins however I didn't think/realize that the txd pin needed to go to the rxd pin instead. Changing these around allowed me to see the commands & responses being returned from the module.
To actually get the gprs working I also needed to temporarily set the pwr pin to low then high.
I am having a problem where I am unable to connect 2 SPI devices to my MkrZero. One device is a CAN shield and the other is an Ethernet Shield .
Both work fine on their own without the other connected but don't seem to work when both connected at the same time. This makes me think that my wiring and code is correct but something is still missing.
The CAN section initializes no matter what, execution seems to stop at the Ethernet code. But the Ethernet code works fine when the CAN wires are disconnected.
I have tried manually setting the CS pins, this doesn't do much. Even with both pins held high CAN starts up. This implies that the libraries take control of the pins.
I have read various tutorials on how to connect multiple devices with SPI but most times the devices are duplicates. My devices are different. I have connected the SPI pins exactly as I should with different CS pins for each device but the problem persists.
Here is my code
#include <CAN.h> //https://github.com/sandeepmistry/arduino-CAN
#include <MCP2515.h> //https://github.com/sandeepmistry/arduino-CAN Changes CS and Int pins from Uno to MkrZero configuration
#include <Ethernet.h>
#include <ArduinoJson.hpp>
#include <ArduinoJson.h>
#include <PubSubClient.h>
#include <Losant.h>
#include <SPI.h>
//Ethernet setup
#define MQTT_MAX_TRANSFER_SIZE 80 //this was done as a result of troubleshooting
byte mac[] = { 0x2C, 0xF7, 0xF1, 0x08, 0x19, 0x2C };
IPAddress ip (192, 168, 0, 1);
EthernetClient client;
// ** Configure the Losant credentials to enable comms over mqtt **
const char* LOSANT_DEVICE_ID = "";
const char* LOSANT_ACCESS_KEY = "";
const char* LOSANT_ACCESS_SECRET = "";
LosantDevice device(LOSANT_DEVICE_ID);
// The setup() function runs once each time the micro-controller starts
void setup()
{
Serial.begin(9600);
while(!Serial) { }
Serial.println("started UART");
//pinMode(BUTTON_PIN, INPUT);
// disable SD SPI
pinMode(4,OUTPUT);
digitalWrite(4,HIGH);
//starting ethernet
Ethernet.init(6); //changing Ethernet shield software select pin to 6 since default is an SPI transfer pin
Serial.println("ethernet about to start");
while(!Ethernet.begin(mac)) {}
Serial.println("ethernet started");
while (!CAN.begin(200E3)) {
Serial.println("Starting CAN failed! ");
delay(250);
}
Serial.println("CAN started");
delay(100);
Does anybody have any ideas on how to troubleshoot this or what the problem is?
There have been a few answers that involve not assuming the SPI bus has been kept the same from the last transaction. I need to reset SPI parameters each time I send a transaction. After going though the libraries I have seen that SPI.begintransaction() is called before every SPI communication, which according to my knowledge, resets the parameters. This implies that I don't need to manually change the SPI bus parameters before each transaction. Am I wrong in this regard?
SPI bus is really simple, and there should be no problem in connecting multiple slaves, as long as, at any time, only one of them has CS_ asserted (low). It can be expected that a library takes control of the CS_ pin, but it also should deassert it after the job is done. If not, then the library would be a very bad one.
You should check hardware and software.
Hardware: use a scope with memory, and look at what happens during initialization. May be that the CS_ pins need a pull-up resistor (the library, if it takes control of its CS_ pin, could choose to put it in high-impedance instead of driving it high). If you don't have a scope you can perhaps monitor the pins by software.
Software: may be the libraries use interrupts? In that case, the program can do things you are unaware of, for example a library can poll a device in background and mess with your code or one from another library. You have to dive deep in the libraries documentation and code. Again, a scope would help a lot.
You didn't specify much about your setup, and your tentative to "manually deselect the CS_ pins) is really worrying. You should check twice that point - if the CS_ pin is high, there is no reason the other SPI device does not work.
Problem was with the level shifter. I connected the OE enable pin to CAN CS, which puts the chip in high impedance when it isn't being used and enables it when I want to send data.
I used my scope to connect to the SPI pins and recorded what was happening. All was working well till I got to MISO. The level shifter was messing with it and pulling it to ground. Basically silencing output from one of the shields.
The learning here is when using level shifters with SPI devices connect the CS to OE.
I am Using STM32F767ZI MCU on Nucleo 144 board, C++ as programming language and IAR embedded workbench IDE.
TXIS bit flag Status is never getting Set (1) even when the I2C is enabled and there is no data in TXDR register.
What I have also noticed that although both master and slave have same Slave address in the relevant registers but NO ADDCODE occurs. Although as evident from code I am using the Polling method. ADDCODE register should have same address as slave address which is not happening as well.
Hardware settings have been verified as correct.
Trying to perform Loopback test on same MCU using I2C1 as master transmitter and I2C2 as slave receiver. Code is getting stuck at part as below:
while(!(IsTXISset())) // Code is getting stuck here
{
}
Where IsTXISset() is as below:
bool I2CInterface_c::IsTXISset(void) const
{
bool flag{false};
volatile uint32_t isrreg = I2C_ISR.Get();
isrreg &= TXISFLAG; //TXISFLAG = 0x02 i.e the only bit position of the TXIS is set as high
if(isrreg == TXISFLAG)
{
flag = true;
}
return flag;
}
Can Anybody assist with that please?
Finally, managed to resolve the issue after noticing that GPIO pins were not setting up properly in Alternative function open drain mode.
Second problem identified after slave started acknowledging the address match no data transfer was taking place which got resolved by writing a routine to clear the ADDR bit is ISR register of I2C.
New developer, Linux, C++, USB - Serial Adapter.
I've completed a program where I am able to write to the USB port. However, if I change my code, make, log back in as root, and try to write to the port again, it doesn't go through. It'll only work if I remove the USB cable from the computer and reseat it before attempting sending data again. If you need more info let me know.
I'm on two different computers and have no way of copying and pasting but here is the gist of what I'm doing.
int fd = 0;
int iOut = 0;
char *ComPort = "/dev/ttyUSB0";
fd=open(ComPort, O_CREAT | O_RDWR | O_NOCTTY | O_NDELAY);
if(fd == -1)
cout << "unable to open" << endl;
// blah blah getting data ready to be sent
// create a block of 50 hex characters to be sent : DB
iOut = write(fd, $DB, sizeof(DB));
// blah blah error checking
close(fd);
return(0);
#Surt #alexfarber I had a talk with a coworker on this and we concluded that this is most likely a hardware issue with my display or usb to serial adapter. I believe the only way this can work with this particular adapter is by turning off the power to it and turning it back on in order to reflect what it would see when being removed and reseated manually. I dont believe this is possible but I'll start another thread with anything I may run into. I appreciate you all taking the time to help with this, I did learn a number of other things I didn't know before hand so this was still very helpful. Thank you once again.
Take at look at chapter 3.2 here http://www.tldp.org/HOWTO/Serial-Programming-HOWTO/x115.html
add some of the error checking first so you can see where if fails. The perror line will help there.
if (fd <0) {perror(ComPort ); exit(-1); } // note the exit which your code doesn't have.
This should now tell you some more info and add
if (errno) {perror(ComPort ); exit(-1); }
after all operations, read, write and set things on the fd.
now add the newtio part of 3.2 to your program in case some handshake failed. You must change it so it conforms with the display.
The final version of your program might be more like 3.3.
I recently got my hands on an Arduino (Uno), and I was wondering something.
I've got no external volume changer for my speakers, so I thought, maybe hook up a potentiometer to the Arduino, and then use that to control the volume (in Windows). But is that possible?
To read a value of an Arduino pin using maybe Visual C, C++ (or some more 'multi-platform' language)? And then using that to set the volume level in Windows (and if it's possible also in Linux).
I thought it might be possible, because if you use:
Serial.println(analogRead([pin with potentiometer]));
You can get the values of the potentiometer to the pc (via USB). So is there any way to read those values in C or C++?
I know how to set the volume in Windows via C or C++, I only need to know if there is a way to read out the values of a potentiometer in a (Visual) C or C++ script.
Definitely. And using exactly the same method: serial communication. Since I'm not a great Windows expert, I can't write you a complete Windows example, but here are some snippets that may get you started on a Unix (Linux, OS X, etc.):
Code on the Arduino:
#define POT_PIN 1
void setup()
{
Serial.begin(9600); // 9600 baud is more than enough
}
void loop()
{
int pot = analogRead(POT_PIN);
unsigned char byte = (pot + 2) >> 2; // round and divide by 4
Serial.write(pot);
delay(100); // or do something useful
}
Code on the computer:
#include <termios.h>
struct termios tio;
memset(&tio, 0, sizeof(tio));
// Open serial port in mode `8N1', non-blocking
tio.c_cflag = CS8 | CREAD | CLOCAL;
tio.c_cc[VMIN] = 1;
tio.c_cc[VTIME] = 5;
int fd = open(device, O_RDONLY);
cfsetospeed(&tio, B9600);
cfsetispeed(&tio, B9600);
tcsetattr(fd, TCSANOW, &tio);
while (1) {
unsigned char byte;
read(fd, &byte, 1);
use_some_library_to_set_volume(byte);
}
There are some things to consider.
You want the PC to listen to your "potentiometer Arduino" only. You don't want it to listen to any random USB data coming at any port. There is a need to create a data protocol which is somewhat unique to your device. If you just spam analog readings you'll get some raw data like "123 128 133 145", which could mean anything and come from any kind of device.
When you type Serial.whatever, the Arduino is likely spitting out an UART signal. I don't know a thing about Arduino, but hopefully it has either RS-232 or USB circuitry on board. You will need a matching port on the PC, the traditional RS-232 9 pin d-sub connector is getting increasingly rare on modern computers. You might need a RS-232 to USB converter.
You need a mean to determine which COM port the device is connected to. USB ports and traditional RS-232 ports work the same, as far as the PC is concerned. Either let the user pick the port manually, or design a more intelligent algorithm to find the port where your device is connected.
Study the Windows API for all the serial port routines. Documentation and examples at MSDN.