Related
Here is the scenario. I have an esp32, 2 led's and a ios example app I found online here. Currently If I press a button on my esp32 it notifies the ios app to display "1", if pressed again it displays "0". This works perfectly.
The tricky part is that this ios app allows me to send a write command to the esp32. I'd like to make it so if '1' is sent LED A turns ON and LED B turns OFF, then LED A OFF and LED B ON when 0 is sent. I am unable to do this though. Try as I might I can't figure out where in the chain of this project something is wrong. Maybe the code on the esp32 or maybe the app i'm unsure.
Here is my arduino code. (There is more to the code not mentioned, I actually have 4 led's but I only want to turn on 2 certain ones when a write command is sent).
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
BLEServer* pServer = NULL;
BLECharacteristic* pCharacteristic = NULL;
bool deviceConnected = false;
bool oldDeviceConnected = false;
boolean oldState = LOW;
uint32_t value = 0;
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
deviceConnected = true;
};
void onDisconnect(BLEServer* pServer) {
deviceConnected = false;
}
};
class MyCallbacks: public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {
std::string rxValue = pCharacteristic->getValue();
if (rxValue.length() > 0) {
Serial.print("Received Value: ");
for (int i = 0; i < rxValue.length(); i++) {
Serial.print(rxValue[i]);
}
Serial.println();
if (rxValue.find("1") != -1) {
digitalWrite(13, HIGH);
digitalWrite(27, LOW);
}
else if (rxValue.find("0") != -1) {
digitalWrite(13, LOW);
digitalWrite(27, HIGH);
}
}
}
};
const int bt1 = 14;
boolean bt1g = true;
int bt1t = 0;
void setup() {
pinMode(13, OUTPUT);
pinMode(15, OUTPUT);
pinMode(33, OUTPUT);
pinMode(27, OUTPUT);
pinMode(bt1, INPUT_PULLUP);
Serial.begin(9600);
BLEDevice::init("ESP32");
pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
BLEService *pService = pServer->createService(SERVICE_UUID);
pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_WRITE |
BLECharacteristic::PROPERTY_NOTIFY
);
pCharacteristic->addDescriptor(new BLE2902());
pService->start();
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID(SERVICE_UUID);
pAdvertising->setScanResponse(false);
pAdvertising->setMinPreferred(0x0);
BLEDevice::startAdvertising();
Serial.println("Waiting a client connection to notify...");
}
void loop()
{
if (bt1g) {
if (digitalRead(bt1) == LOW ) {
bt1t = (bt1t + 1) % 2;
Serial.println(bt1t);
bt1g = false;
}
}
if (!bt1g) {
if (digitalRead(bt1) == HIGH) {
bt1g = true;
}
}
if (bt1t == 0) {
digitalWrite(15, LOW);
digitalWrite(33, HIGH);
}
}
boolean newState = digitalRead(15);
if (deviceConnected) {
if (newState != oldState) {
if (newState == LOW) {
pCharacteristic->setValue("1");
}
else {
pCharacteristic->setValue("0");
}
pCharacteristic->notify();
};
oldState = newState;
}
delay(50);
}
It looks like the entire code for the ios app is too long to submit to this post so here is the github
I'm really unsure and stuck in a rut. Any help is appreciated!
Could it be you are not discovering the correct characteristics? It looks like you only have one service and one characteristic.
I have absolutely no experience in programming serial communication and since I'm stuck with my code I'd really appreciate your help! Thank you already!
So now to my problem:
I got a generator on which are several different sensors who communicate over CAN with a microcontroller. This mc itself communicates with a device from USBTin again over CAN. On the USBTin, a little board, is mainly a CAN controller and a microcontroller which are precoded from its developer.
So my task now is to open my COM Port, send the right messages to the USBTin (those are "S5" for the baudrate and 'O' for Open CAN) and then receive the data.
First of all the functions and my problem:
The problem is that in my output textfield stands something like "PPPPPPPPPP,Râö". There are always these 10 P's and some random characters. I have no idea where the P's or these additional "Râö" comes from. The actual output string shoud be something like "T1E18001F8". I tested that with hTerm, which is a terminal programm for serial communication.
OPEN:
long Serial::Open()
{
if (IsOpened()) return 0;
#ifdef UNICODE
wstring wtext(port.begin(),port.end());
#else
string wtext = port;
#endif
hComm = CreateFile(wtext.c_str(),
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
0);
if (hComm == INVALID_HANDLE_VALUE) {return 1;}
if (PurgeComm(hComm, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR |
PURGE_RXCLEAR) == 0) {return 2;}//purge
//get initial state
DCB dcbOri;
bool fSuccess;
fSuccess = GetCommState(hComm, &dcbOri);
if (!fSuccess) {return 3;}
DCB dcb1 = dcbOri;
dcb1.BaudRate = baud;
if (parity == 'E') dcb1.Parity = EVENPARITY;
else if (parity == 'O') dcb1.Parity = ODDPARITY;
else if (parity == 'M') dcb1.Parity = MARKPARITY;
else if (parity == 'S') dcb1.Parity = SPACEPARITY;
else if (parity == 'N') dcb1.Parity = NOPARITY;
dcb1.ByteSize = (BYTE)dsize;
if(stopbits==2) dcb1.StopBits = TWOSTOPBITS;
else if (stopbits == 1.5) dcb1.StopBits = ONE5STOPBITS;
else if (stopbits == 1) dcb1.StopBits = ONE5STOPBITS;
dcb1.fOutxCtsFlow = false;
dcb1.fOutxDsrFlow = false;
dcb1.fOutX = false;
dcb1.fDtrControl = DTR_CONTROL_DISABLE;
dcb1.fRtsControl = RTS_CONTROL_DISABLE;
fSuccess = SetCommState(hComm, &dcb1);
delay(60);
if (!fSuccess) {return 4;}
fSuccess = GetCommState(hComm, &dcb1);
if (!fSuccess) {return 5;}
osReader = { 0 };// Create the overlapped event. Must be closed before
exiting to avoid a handle leak.
osReader.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (osReader.hEvent == NULL) {return 6;}// Error creating overlapped event;
abort.
fWaitingOnRead = FALSE;
osWrite = { 0 };
osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (osWrite.hEvent == NULL) {return 7;}
if (!GetCommTimeouts(hComm, &timeouts_ori)) { return 8; } // Error getting
time-outs.
COMMTIMEOUTS timeouts;
timeouts.ReadIntervalTimeout = 20;
timeouts.ReadTotalTimeoutMultiplier = 15;
timeouts.ReadTotalTimeoutConstant = 100;
timeouts.WriteTotalTimeoutMultiplier = 15;
timeouts.WriteTotalTimeoutConstant = 100;
if (!SetCommTimeouts(hComm, &timeouts)) { return 9;} // Error setting time-
outs.
return 0;
}
WRITE:
bool Serial::Write(char *data)
{
if (!IsOpened()) {
return false;
}
BOOL fRes;
DWORD dwWritten;
long n = strlen(data);
if (n < 0) n = 0;
else if(n > 1024) n = 1024;
// Issue write.
if (!WriteFile(hComm, data, n, &dwWritten, &osWrite)) {
if (GetLastError() != ERROR_IO_PENDING) {fRes = FALSE;}// WriteFile
failed, but it isn't delayed. Report error and abort.
else {// Write is pending.
if (!GetOverlappedResult(hComm, &osWrite, &dwWritten, TRUE))
fRes = FALSE;
else fRes = TRUE;// Write operation completed successfully.
}
}
else fRes = TRUE;// WriteFile completed immediately.
return fRes;
}
READCHAR:
char Serial::ReadChar(bool& success)
{
success = false;
if (!IsOpened()) {return 0;}
DWORD dwRead;
DWORD length=1;
BYTE* data = (BYTE*)(&rxchar);
//the creation of the overlapped read operation
if (!fWaitingOnRead) {
// Issue read operation.
if (!ReadFile(hComm, data, length, &dwRead, &osReader)) {
if (GetLastError() != ERROR_IO_PENDING) { /*Error*/}
else { fWaitingOnRead = TRUE; /*Waiting*/}
}
else {if(dwRead==length) success = true;}//success
}
//detection of the completion of an overlapped read operation
DWORD dwRes;
if (fWaitingOnRead) {
dwRes = WaitForSingleObject(osReader.hEvent, READ_TIMEOUT);
switch (dwRes)
{
// Read completed.
case WAIT_OBJECT_0:
if (!GetOverlappedResult(hComm, &osReader, &dwRead, FALSE))
{/*Error*/ }
else {
if (dwRead == length) success = true;
fWaitingOnRead = FALSE;// Reset flag so that another
opertion
can be issued.
}// Read completed successfully.
break;
case WAIT_TIMEOUT:
// Operation isn't complete yet.
break;
default:
// Error in the WaitForSingleObject;
break;
}
}
return rxchar;
}
And Finally the excerpt of the main in wxWidgets to display the received data:
void GUI_1_2Frame::OnConnectButtonClick(wxCommandEvent& (event))
{
char tempString[10] = {0};
bool ReadChar_success = true;
char temp_Char;
/* Preset Serial Port setting */
Serial com(com_x, 115200, 8, NOPARITY, 1);
char* buffer;
if(connection_flag)
{
/* Port was connected, Disconnect Button unsed*/
com.Close();
wxMessageBox(_("Port closed"),_("Info!"),wxICON_INFORMATION);
connection_flag = 0;
ConnectButton->SetLabel("Connect");
TextCtrl1->SetValue("");
}
else
{
/* If open() == true -> INVALID HANDLE */
if(com.Open())
{
wxMessageBox(_("Port not available"),_("ERROR!"),wxICON_ERROR);
}
else /* Port Opened */
{
TextCtrl1->SetValue(com.GetPort());
ConnectButton->SetLabel("Disconnect");
connection_flag = 1;
}
if(com.Write("S5"))
{
TextCtrl1->SetValue("Baudrate sent!\n");
delay(100);
if(com.WriteChar('O'))
{
TextCtrl1->SetValue("Baudrate & Open Command sent!");
int i =0;
while(i<10)
{
temp_Char = com.ReadChar(ReadChar_success);
tempString[i] = temp_Char;
i++;
}
com.WriteChar('C');
com.Close();
//com.readSerialPort(data, MAX_DATA_LENGTH);
TextCtrl2->SetValue(tempString);
//wxMessageOutput::Get()->Printf("%s", tempString);
}
else
{
TextCtrl1->SetValue("Open Command Error!"); }
}
else
{
TextCtrl1->SetValue("Error!");
}
}
}
Since I am not native speaking englisch I say sorry for my language mistakes.
Thank everybody a lot and again I really appreciate every single hint!
Greetings,
MSol
I am trying to write a program where arduino receives text from the gsm module.But my program is able to read the first text and perform a duty,but i want it to receive multiple texts and perform individual tasks for each respective texts?Any help will be great.Thank You.
#include <SoftwareSerial.h>
SoftwareSerial gsm(2, 3);
String inString[64]; // string to hold input coming from device
String read;
int count = 0;
boolean verifyingDone = false; // flags to determine the action completed and to perform next action
boolean regist = false;
boolean registercomplete = false;
boolean location = false;
void setup()
{
// put your setup code here, to run once:
Serial.begin(9600);
gsm.begin(4800);
delay(100);
gsm.print("ate0\r"); // removes the echo from the device
delay(100);
gsm.print("at+cnmi=1,2,0,0,0\r"); // to receive a text
Serial.print("The Device has been Intiated");
}
void loop() {
if (gsm.available())
{
while (gsm.available())
{
read = gsm.readString();
verifyNum(); // verifying the number
/* verifyingDone=true;
if(verifyingDone){
delay(1000);
gsm.print("at+cgpsinfo\r");
delay(1000);
checkGps();
verifyingDone=false;
*/
reading1: inString[count++] = read;
Serial.print(String(read));
if (count == 64) {
break;
}
}
delay(200);
count = 0;
}
}
void clearBufferArray()
{
for (int i = 0; i < count; i++)
{
inString[i] = "";
}
}
void verifyNum() {
if (read.startsWith("\r\n+CMT: ")) { // checking the incoming text and verifying the pre-defined number
int index1 = read.indexOf('"');
int index2 = read.indexOf('"', index1 + 1);
String Number = read.substring(index1 + 2, index2);
char floatbuf[100]; // make this at least big enough for the whole string
Number.toCharArray(floatbuf, 100);
int number = atoi(floatbuf);
//Serial.println(number);
delay(1000);
if (strcmp(number, 24190) == 0)
{
Serial.println("The Sending number is " + Number);
Serial.println("This is the registered number");
regist = true;
if (regist) {
gsm.print("AT+CMGS=\"0434519166\"\r"); // Sending registeration confirmation via sms
delay(100);
gsm.print("Success this mobile number has been registered .\r");
gsm.print("\r");
delay(100);
gsm.println((char)26);
delay(10000);
registercomplete = true;
if (regist == true && registercomplete == true) { //after complete registeration ,checking the gps and sending the co-ordinates
checkGps();
delay(500);
}
}
else {
gsm.print("AT+CMGSO=\"0434519166\" \,\"Someone tried to access your device\"\r"); // When not a registered number
}
}
}
}
void checkGps()
{
Serial.print("Gps Search has started");
delay(10000);//big delay to complete previous process //Not able to do this process completely------>Coz not able to re-read the string obtained from the first read..have to find an alternate to read incoming signals efficiently and re-using it
clearBufferArray();
delay(1000);
gsm.write("at+cgpsinfo\r");
delay(10000);
Serial.println();
Serial.println();
Serial.print("Locating.....Wait for a moment");
/*int spacePosition = read.indexOf(':');
if (read.charAt(spacePosition + 1) == ',' && regist==true )*/
if (read.startsWith("\r\n+CGPINFO:,,,"))
{
Serial.println("GPS signal not found.Go outside"); //
gsm.print("AT+CMGS=\"0434519166\"\r"); // Sending location as sms
delay(100);
gsm.print("GPS signal not found.Go outside ");
gsm.print("\r");
delay(100);
gsm.println((char)26);
delay(1000);
regist = false;
}
else
{
Serial.println("Signal found");
gsm.print("AT+CMGS=\"0434519166\"\r"); //Confirming signal found and sending location----->location finding programs can be obtained from previouses sketches
delay(100);
gsm.print("GPS found.Location will be sent soon ");
gsm.print("\r");
delay(100);
gsm.println((char)26);
delay(1000);
}
}
Thank You,Above code is justa tryout ,any help is welcome!
- (void)openPlayThreadWithRtmpURL:(NSString *)rtmpURL {
spx_int16_t *input_buffer;
do {
if (self.rtmpDelegate) {
[self.rtmpDelegate evenCallbackWithEvent:2000];
}
//init speex decoder and config;
speex_bits_init(&dbits);
dec_state = speex_decoder_init(&speex_wb_mode);
speex_decoder_ctl(dec_state, SPEEX_GET_FRAME_SIZE, &dec_frame_size);
input_buffer = malloc(dec_frame_size * sizeof(short));
NSLog(#"Init Speex decoder success frame_size = %d",dec_frame_size);
//init rtmp
pPlayRtmp = RTMP_Alloc();
RTMP_Init(pPlayRtmp);
NSLog(#"Play RTMP_Init %#\n", rtmpURL);
if (!RTMP_SetupURL(pPlayRtmp, (char*)[rtmpURL UTF8String])) {
NSLog(#"Play RTMP_SetupURL error\n");
if(self.rtmpDelegate) {
[self.rtmpDelegate evenCallbackWithEvent:2002];
}
break;
}
if (!RTMP_Connect(pPlayRtmp, NULL) || !RTMP_ConnectStream(pPlayRtmp, 0)) {
NSLog(#"Play RTMP_Connect or RTMP_ConnectStream error\n");
if(self.rtmpDelegate) {
[self.rtmpDelegate evenCallbackWithEvent:2002];
}
break;
}
if(self.rtmpDelegate) {
[self.rtmpDelegate evenCallbackWithEvent:2001];
}
NSLog(#"Player RTMP_Connected \n");
RTMPPacket rtmp_pakt = {0};
isStartPlay = YES;
while (isStartPlay && RTMP_ReadPacket(pPlayRtmp, &rtmp_pakt)) {
if (RTMPPacket_IsReady(&rtmp_pakt)) {
if (!rtmp_pakt.m_nBodySize) {
continue;
}
if (rtmp_pakt.m_packetType == RTMP_PACKET_TYPE_AUDIO) {
NSLog(#"Audio size = %d head = %d time = %d", rtmp_pakt.m_nBodySize, rtmp_pakt.m_body[0], rtmp_pakt.m_nTimeStamp);
speex_bits_read_from(&dbits, rtmp_pakt.m_body + 1, rtmp_pakt.m_nBodySize - 1);
speex_decode_int(dec_state, &dbits, input_buffer); //audioData in the input_buffer
//do something...
} else if (rtmp_pakt.m_packetType == RTMP_PACKET_TYPE_VIDEO) {
// 处理视频数据包
} else if (rtmp_pakt.m_packetType == RTMP_PACKET_TYPE_INVOKE) {
// 处理invoke包
NSLog(#"RTMP_PACKET_TYPE_INVOKE");
RTMP_ClientPacket(pPlayRtmp,&rtmp_pakt);
} else if (rtmp_pakt.m_packetType == RTMP_PACKET_TYPE_INFO) {
// 处理信息包
//NSLog(#"RTMP_PACKET_TYPE_INFO");
} else if (rtmp_pakt.m_packetType == RTMP_PACKET_TYPE_FLASH_VIDEO) {
// 其他数据
int index = 0;
while (1) {
int StreamType; //1-byte
int MediaSize; //3-byte
int TiMMER; //3-byte
int Reserve; //4-byte
char* MediaData; //MediaSize-byte
int TagLen; //4-byte
StreamType = rtmp_pakt.m_body[index];
index += 1;
MediaSize = bigThreeByteToInt(rtmp_pakt.m_body + index);
index += 3;
TiMMER = bigThreeByteToInt(rtmp_pakt.m_body + index);
index += 3;
Reserve = bigFourByteToInt(rtmp_pakt.m_body + index);
index += 4;
MediaData = rtmp_pakt.m_body + index;
index += MediaSize;
TagLen = bigFourByteToInt(rtmp_pakt.m_body + index);
index += 4;
//NSLog(#"bodySize:%d index:%d",rtmp_pakt.m_nBodySize,index);
//LOGI("StreamType:%d MediaSize:%d TiMMER:%d TagLen:%d\n", StreamType, MediaSize, TiMMER, TagLen);
if (StreamType == 0x08) {
//音频包
//int MediaSize = bigThreeByteToInt(rtmp_pakt.m_body+1);
// LOGI("FLASH audio size:%d head:%d time:%d\n", MediaSize, MediaData[0], TiMMER);
speex_bits_read_from(&dbits, MediaData + 1, MediaSize - 1);
speex_decode_int(dec_state, &dbits, input_buffer);
//[mAudioPlayer putAudioData:input_buffer];
// putAudioQueue(output_buffer,dec_frame_size);
} else if (StreamType == 0x09) {
//视频包
// LOGI( "video size:%d head:%d\n", MediaSize, MediaData[0]);
}
if (rtmp_pakt.m_nBodySize == index) {
break;
}
}
}
RTMPPacket_Free(&rtmp_pakt);
}
}
if (isStartPlay) {
if(self.rtmpDelegate) {
[self.rtmpDelegate evenCallbackWithEvent:2005];
}
isStartPlay = NO;
}
} while (0);
[mAudioPlayer stopPlay];
if (self.rtmpDelegate) {
[self.rtmpDelegate evenCallbackWithEvent:2004];
}
if (RTMP_IsConnected(pPlayRtmp)) {
RTMP_Close(pPlayRtmp);
}
RTMP_Free(pPlayRtmp);
free(input_buffer);
speex_bits_destroy(&dbits);
speex_decoder_destroy(dec_state);
}
This is my custom method. RtmpURL is a NSString'S object, it is a stream server address. Use this method, I can get the encoded of audio stream from the server, after that, I use speex decoder to decode the data that I got, just like this:
//init speex decoder and config;
speex_bits_init(&dbits);
dec_state = speex_decoder_init(&speex_wb_mode);
speex_decoder_ctl(dec_state, SPEEX_GET_FRAME_SIZE, &dec_frame_size);
input_buffer = malloc(dec_frame_size * sizeof(short));
NSLog(#"Init Speex decoder success frame_size = %d",dec_frame_size);
if (rtmp_pakt.m_packetType == RTMP_PACKET_TYPE_AUDIO) {
NSLog(#"Audio size = %d head = %d time = %d", rtmp_pakt.m_nBodySize, rtmp_pakt.m_body[0], rtmp_pakt.m_nTimeStamp);
speex_bits_read_from(&dbits, rtmp_pakt.m_body + 1, rtmp_pakt.m_nBodySize - 1);
speex_decode_int(dec_state, &dbits, input_buffer); //audioData in the input_buffer
//do something...
}
Now, decoded of audio data are stored in the input_buffer, and this is my confusion. How do I use the AudioUnit to play the audio data.And this is my playback callback function:
OSStatus playCallback(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData){
AudioPlayer *THIS = (__bridge AudioPlayer *)inRefCon;
//How do I use the AudioUnit to play the audio stream from server?
return noErr;
}
I hope some friends to solve my confusion, if you were used the audioUnit, Thank you so much!
In your playCallback, you need to copy the audio into the buffer ioData.
For example
memcpy (ioData->mBuffers[0].mData, input_buffer + offset, numBytes );
// increase offset based on how many frames it requests.
The input variable inNumberFrames is the number of frames that it is ready for. This might be less than the number of frames in input_buffer. So you need to keep track of your play position.
I do not know your audio format this specified in your audio stream basic description. You need to calculate how many bytes need copied considering mono/stereo, number of bytes per channel, and of course inNumberFrames.
There are some very good resources here link
Iam working on a program to perform addition,subtraction,multiplication and differentiation operations on a polynomial using linked list in c.
The other operations are working fine except multiplication one.
here is the code
#include<stdio.h>
#include<malloc.h>
#include<conio.h>
struct link{
int coeff;
int pow;
struct link *next;
};
struct link *poly1=NULL,*poly2=NULL,*poly=NULL;
void create(struct link *node)
{
char ch;
do
{
printf("\n\nenter coeff:");
scanf("%d",&node->coeff);
printf("\nenter power:");
scanf("%d",&node->pow);
node->next=(struct link*)malloc(sizeof(struct link));
node=node->next;
node->next=NULL;
printf("\ncontinue(y/n):");
ch=getch();
}
while(ch=='y' || ch=='Y');
}
void show(struct link *node)
{
while(node->next!=NULL)
{
printf("%dx^%d",node->coeff,node->pow);
node=node->next;
if(node->next!=NULL)
printf(" + ");
}
}
void polyadd(struct link *poly1,struct link *poly2,struct link *poly)
{
while(poly1->next && poly2->next)
{
if(poly1->pow>poly2->pow)
{
poly->pow=poly1->pow;
poly->coeff=poly1->coeff;
poly1=poly1->next;
}
else if(poly1->pow<poly2->pow)
{
poly->pow=poly2->pow;
poly->coeff=poly2->coeff;
poly2=poly2->next;
}
else
{
poly->pow=poly1->pow;
poly->coeff=poly1->coeff+poly2->coeff;
poly1=poly1->next;
poly2=poly2->next;
}
poly->next=(struct link *)malloc(sizeof(struct link));
poly=poly->next;
poly->next=NULL;
}
while(poly1->next || poly2->next)
{
if(poly1->next)
{
poly->pow=poly1->pow;
poly->coeff=poly1->coeff;
poly1=poly1->next;
}
if(poly2->next)
{
poly->pow=poly2->pow;
poly->coeff=poly2->coeff;
poly2=poly2->next;
}
poly->next=(struct link *)malloc(sizeof(struct link));
poly=poly->next;
poly->next=NULL;
}
}
void polysub(struct link *poly1,struct link *poly2,struct link *poly)
{
while(poly1->next && poly2->next)
{
if(poly1->pow>poly2->pow)
{
poly->pow=poly1->pow;
poly->coeff=poly1->coeff;
poly1=poly1->next;
}
else if(poly1->pow<poly2->pow)
{
poly->pow=poly2->pow;
poly->coeff=poly2->coeff;
poly2=poly2->next;
}
else
{
poly->pow=poly1->pow;
poly->coeff=poly1->coeff-poly2->coeff;
poly1=poly1->next;
poly2=poly2->next;
}
poly->next=(struct link *)malloc(sizeof(struct link));
poly=poly->next;
poly->next=NULL;
}
while(poly1->next || poly2->next)
{
if(poly1->next)
{
poly->pow=poly1->pow;
poly->coeff=poly1->coeff;
poly1=poly1->next;
}
if(poly2->next)
{
poly->pow=poly2->pow;
poly->coeff=poly2->coeff;
poly2=poly2->next;
}
poly->next=(struct link *)malloc(sizeof(struct link));
poly=poly->next;
poly->next=NULL;
}
}
void polymul(struct link *n1, struct link *n2, struct link *n)
{
struct link * n2beg=n2;
while (n1)
{
struct link * temp=(struct link *)malloc(sizeof(struct link));
temp->next=NULL;
n2=n2beg;
while (n2)
{
temp->coeff = n1->coeff * n2->coeff;
temp->pow = n1->pow + n2->pow;
n2 = n2->next;
temp->next=(struct link *)malloc(sizeof(struct link));
temp=temp->next;
temp->next=NULL;
}
polyadd(temp,n,n);
n1 = n1->next;
free(temp);
}
}
void diff(struct link* p1,struct link* p2)
{
while(p1->next!=NULL)
{
p2->coeff=p1->coeff*p1->pow;
p2->pow=p1->pow-1;
p2->next=NULL;
p2->next=(struct link *)malloc(sizeof(struct link));
p2=p2->next;
p2->next=NULL;
p1=p1->next;
}
}
main()
{
int op;
char ch;
do{
poly1=(struct link *)malloc(sizeof(struct link));
poly2=(struct link *)malloc(sizeof(struct link));
poly=(struct link *)malloc(sizeof(struct link));
printf("\n\nWhat do you want to do?\n1.Addition\n2.Subtraction
\n3.Multiplication\n4.Differentiation\n0.Exit
\nEnter your choice:");
scanf("%d",&op);
switch(op)
{
case 1:
printf("\n\nenter 1st polynomial:");
create(poly1);
printf("\n\nenter 2nd polynomial:");
create(poly2);
printf("\n1st Polynomial:\t");
show(poly1);
printf("\n2nd Polynomial:\t");
show(poly2);
polyadd(poly1,poly2,poly);
printf("\nAdded polynomial:\t");
show(poly);
break;
case 2:
printf("\n\nenter 1st polynomial:\t");
create(poly1);
printf("\n\nenter 2nd polynomial:\t");
create(poly2);
printf("\n\n1st Polynomial:\t");
show(poly1);
printf("\n\n2nd Polynomial:\t");
show(poly2);
polysub(poly1,poly2,poly);
printf("\n\nSubtracted polynomial:\t");
show(poly);
break;
case 3:
printf("\n\nenter 1st polynomial:");
create(poly1);
printf("\n\nenter 2nd polynomial:");
create(poly2);
printf("\n\n1st Polynomial:\t");
show(poly1);
printf("\n\n2nd Polynomial:\t");
show(poly2);
polymul(poly1,poly2,poly);
printf("\n\nMultiplied polynomial:\t");
show(poly);
break;
case 4:
printf("\n\nenter polynomial:");
create(poly1);
printf("\n\nPolynomial:\t");
show(poly1);
diff(poly1,poly2);
printf("\n\nDifferentiated Polynomial:\t");
show(poly2);
break;
}
/* printf("\n Want to continue? Y/N:");
ch=getch();*/
}
while(op);
}
polyadd(temp,n,n) as used in polymul() has trouble coping with using n as a source polynomial and as the sum destination polynomial.
Either re-work polyadd() to cope with parameters that point to the same polynomial or re-work the call of polyadd() in polymul() to use distinct polynomials. Suggest the first.
I did not go through your full code, as I found an error in your create() function. Note that you have passed poly1 to the function create() as argument.
This not correct as C follows call by value. What happens is only the value of poly1 (which is still un-initialised) is passed and *node stores that value. It's better to pass the address of poly1 as argument and catch that value in the function using pointer to pointer.
#include<stdio.h>
#include <conio.h>
struct node
{
int c,e;
struct node *link;
}*start1=NULL,*start2=NULL,*start3=NULL,*temp1,*temp2,*temp3,*new_node;
int delete_dup(int h)
{
struct node *cr,*prev,*run,*tmp;
cr = start3->link;
prev = start3;
while(cr != NULL){
run = start3;
while(run != cr)
{
if(run->e == cr->e)
{
run->c+=cr->c;
tmp = cr;
cr = cr->link;
prev->link = cr;
remove(tmp);h--;
break;
}
run = run->link;
}
if(run == cr){
cr = cr->link;
prev = prev->link;
}
}
return h;
}
void main()
{
int n,m,i,j,k;
puts("Enter the number of terms in first polynomial");
scanf("%d",&n);
for(i=0;i<n;i++)
{
new_node=(struct node*)malloc(sizeof(struct node));
new_node->link=NULL;
puts("C=");
scanf("%d",&new_node->c);
puts("E=");
scanf("%d",&new_node->e);
new_node->link=start1;
start1=new_node;
}
puts("Enter the number of terms in first polynomial");
scanf("%d",&m);
for(i=0;i<m;i++)
{
new_node=(struct node*)malloc(sizeof(struct node));
new_node->link=NULL;
puts("C=");
scanf("%d",&new_node->c);
puts("E=");
scanf("%d",&new_node->e);
new_node->link=start2;
start2=new_node;
}
temp1=start1;
temp2=start2;
i=0; j=0;
while(i<m)
{
j=0; temp1=start1;
while(j<n)
{
new_node=(struct node*)malloc(sizeof(struct node));
new_node->link=NULL;
new_node->c=temp1->c*temp2->c;
new_node->e=temp1->e+temp2->e;
new_node->link=start3;
start3=new_node;
j++;
temp1=temp1->link;
}
temp2=temp2->link;
i++;
}
i=0;
k=delete_dup(m*n);
temp3=start3;
while(i<k-1)
{
printf("(%dx^%d)+",temp3->c,temp3->e);
temp3=temp3->link;
i++;
}
printf("(%dx^%d)",temp3->c,temp3->e);
}
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
struct node{
int coef,pow;
struct node *next;
};
struct node* create()
{
int c;
struct node *new_node=NULL;
struct node *head=NULL,*temp;
do{
new_node=(struct node*)malloc(sizeof(struct node));
printf("\nEnter coef :");
scanf("%d",&new_node->coef);
printf("\nEnter power : ");
scanf("%d",&new_node->pow);
if(head==NULL)
{
head=new_node;
head->next=NULL;
temp=new_node;
}
else
{
temp->next=new_node;
temp=temp->next;
temp->next=NULL;
}
printf("\nDo you want to continue :");
scanf("%d",&c);
}while(c==1);
return head;
}
void print(struct node *p)
{
while(p!=NULL)
{
printf("|%d|%d|->",p->coef,p->pow);
p=p->next;
}
}
struct node* create_new(int p, int q)
{
struct node *nn=(struct node*)malloc(sizeof(struct node));
nn->coef=p;
nn->pow=q;
nn->next=NULL;
return nn;
}
struct node* add(struct node *poly1,struct node *poly2)
{
struct node *tempadd,*temp;
struct node *temp1=poly1;
struct node *temp2=poly2,*head=NULL;
while(temp1!=NULL && temp2!=NULL)
{
if(temp1->pow==temp2->pow)
{
tempadd=create_new(temp1->coef+temp2->coef,temp2->pow);
temp1=temp1->next;
temp2=temp2->next;
}
else if(temp1->pow<temp2->pow)
{
tempadd=create_new(temp2->coef,temp2->pow);
temp2=temp2->next;
}
else
{
tempadd=create_new(temp1->coef,temp1->pow);
temp1=temp1->next;
}
if(head==NULL)
{
head=tempadd;
temp=head;
}
else
{
temp->next=tempadd;
temp=temp->next;
}
}
if(temp1!=NULL)
{
while(temp1!=NULL)
{
tempadd=create_new(temp1->coef,temp1->pow);
temp1=temp1->next;
temp->next=tempadd;
temp=temp->next;
}
}
else if(temp2!=NULL)
{
while(temp2!=NULL)
{
tempadd=create_new(temp2->coef,temp2->pow);
temp2=temp2->next;
temp->next=tempadd;
temp=temp->next;
}
}
return head;
}
void main()
{
struct node *head1,*head2,*head3;
head1=create();
print(head1);
head2=create();
print(head1);
printf("\n");
print(head2);
printf("\n");
head3=add(head1,head2);
printf("\n\nResult : ");
print(head3);
getch();
}
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef struct node {
struct node *previous;
int coef;
int pow;
struct node *next;
}poly;
poly *locate(int,poly *);
void display(poly *);
poly *mult(poly *,poly *,poly *);
void display2(poly *);
void main()
{
char ch;
poly *s1,*s2,*s3,*head1,*head2,*head3,*s4;;
s1=(poly *)malloc(sizeof(poly));
s1->previous=NULL;
head1=s1;
s2=(poly *)malloc(sizeof(poly));
s2->previous=NULL;
head2=s2;
head3=s3;
printf("Enter first polynomial :\n");
do{ //Input for polynomial-1
printf("Enter co-efficient : ");
scanf("%d",&s1->coef);
printf("Enter exponent : ");
scanf("%d",&s1->pow);
printf("Do you want to enter more terms(Y/N) : ");
scanf(" %c",&ch);
if(ch=='Y'){
s1->next=(poly*)malloc(sizeof(poly));
s1->next->previous=s1;
s1=s1->next;
}
else {
s1->next=NULL;
break;
}
}while(1);
printf("Enter second polynomial : \n");
do{ //input for polynomial-2
printf("Enter co-efficient : ");
scanf("%d",&s2->coef);
printf("Enter exponent : ");
scanf("%d",&s2->pow);
printf("Do you want to enter more terms(Y/N) : ");
scanf(" %c",&ch);
if(ch=='Y'){
s2->next=(poly*)malloc(sizeof(poly));
s2->next->previous=s2;
s2=s2->next;
}
else {
s2->next=NULL;
break;
}
}while(1);
printf("Entered polynomials are : \n");
display(s1);
printf("\n");
display(s2);
s3=NULL;
s4=mult(s1,s2,s3);
printf("Resultant Polynomial after multiplication :\n");
display(s4);
}
void display(poly *a)
{
while(a!=NULL)
{
printf("%dx^%d",a->coef,a->pow);
if(a->previous!=NULL)
printf(" + ");
a=a->previous;
}
}
poly *mult(poly *s1,poly *s2,poly *s3)
{
while(s1->previous!=NULL)
s1=s1->previous;
while(s2->previous!=NULL)
s2=s2->previous;
while(s1)
{
while(s2->previous!=NULL)
s2=s2->previous;
while(1)
{
if(s2->next!=NULL)
{
poly *s4;
if(s3==NULL)
{
s3=(poly *)malloc(sizeof(poly));
s3->pow=s1->pow+s2->pow;
s3->coef=s1->coef*s2->coef;
s3->previous==NULL;
s3->next==NULL;
}
else
{
s4=locate(s1->pow+s2->pow,s3);
if(s4==NULL)
{
s3->next=(poly *)malloc(sizeof(poly));
s3->next->previous=s3;
s3=s3->next;
s3->pow=s1->pow+s2->pow;
s3->coef=s1->coef*s2->coef;
s3->next==NULL;
}
else
{
s4->coef=(s4->coef)+(s1->coef*s2->coef);
}
}
s2=s2->next;
}
else
{
poly *s4;
if(s3==NULL)
{
s3=(poly *)malloc(sizeof(poly));
s3->pow=s1->pow+s2->pow;
s3->coef=s1->coef*s2->coef;
s3->previous==NULL;
s3->next==NULL;
}
else{
s4=locate(s1->pow+s2->pow,s3);
if(s4==NULL)
{
s3->next=(poly *)malloc(sizeof(poly));
s3->next->previous=s3;
s3=s3->next;
s3->pow=s1->pow+s2->pow;
s3->coef=s1->coef*s2->coef;
s3->next==NULL;
}
else
{
s4->coef=s4->coef+s1->coef*s2->coef;
}
}
break;
};
}s1=s1->next;
}return s3;
}
poly *locate(int exp,poly *s3)
{
if(s3==NULL)
{
return NULL;
}
else if(s3->pow==exp)
{
return s3;
}
else{
return locate(exp,s3->previous);
}
}
I considered the first term of first polynomial and multiplied with all the terms of second polynomial thereby creating a primary linked list of multiplied polynomial. As next piece of code I considered next term of first polynomial and then multiplied and searched in the multiplied polynomial for the same index and added the result to it, If it is not present I created a new node in the multiplied polynomial.
Happy Coding